home *** CD-ROM | disk | FTP | other *** search
/ Qu-ake / Qu-ake.iso / qu_ke / patches / 024 / KALQUAKE.PAT < prev    next >
Encoding:
Text File  |  1996-10-25  |  106.1 KB  |  3,919 lines

  1. diff -ur --new-file v106qc/chain.qc kalq-src/chain.qc
  2. --- v106qc/chain.qc    Thu Jan  1 00:00:00 1970
  3. +++ kalq-src/chain.qc    Tue Oct 22 15:02:14 1996
  4. @@ -0,0 +1,222 @@
  5. +
  6. +/************\
  7. +* BreakChain *
  8. +\************/
  9. +
  10. +void (entity Head) BreakChain =
  11. +{
  12. +        local entity link;
  13. +
  14. +        link = Head.goalentity;
  15. +        while (link != world)
  16. +        {
  17. +                Head = link.goalentity;
  18. +                remove (link);
  19. +                link = Head;
  20. +        }
  21. +};
  22. +
  23. +/*********\
  24. +* LinkPos *
  25. +\*********/
  26. +
  27. +void () LinkPos =
  28. +{
  29. +        makevectors (self.enemy.angles);
  30. +        setorigin (self, self.owner.origin + ( ( ( self.enemy.origin + 
  31. +                (v_up * 16 * (!self.enemy.button2)) + (v_forward * 16) ) - self.owner.origin ) *
  32. +                ( self.weapon ) ) );
  33. +        self.nextthink = time + 0.01;
  34. +};
  35. +
  36. +/***********\
  37. +* MakeChain *
  38. +\***********/
  39. +
  40. +entity (entity head, entity tail, float num) MakeChain =
  41. +{
  42. +        local entity link, prevlink;
  43. +        local float linknum;
  44. +
  45. +        linknum = num;
  46. +        num = num + 1;
  47. +        prevlink = world;
  48. +        while (linknum > 0)
  49. +        {
  50. +                link = spawn();
  51. +
  52. +                link.goalentity = prevlink;
  53. +                prevlink = link;
  54. +
  55. +                link.owner = head;
  56. +                link.enemy = tail;
  57. +                link.weapon = linknum / num;
  58. +                link.movetype = MOVETYPE_NOCLIP;
  59. +                link.solid = SOLID_NOT;
  60. +                link.angles_z = 51 * linknum;
  61. +                link.angles_y = 41 * linknum;
  62. +                link.angles_x = 31 * linknum;
  63. +                link.avelocity = '310 410 510';
  64. +                setmodel (link, "progs/s_spike.mdl");
  65. +                setsize (link, '0 0 0', '0 0 0');
  66. +                makevectors (tail.angles);
  67. +                setorigin (link, head.origin + ( ( ( tail.origin 
  68. +                        + (v_up * 16 * (!tail.button2)) + ( v_forward * 16 ) ) - head.origin )
  69. +                        * ( link.weapon ) ) );
  70. +                link.nextthink = time + 0.01;
  71. +                link.think = LinkPos;
  72. +                linknum = linknum - 1;
  73. +        }
  74. +        return link;
  75. +};
  76. +
  77. +
  78. +/************\
  79. +* HookVanish *
  80. +\************/
  81. +
  82. +void () HookVanish =
  83. +{
  84. +        self.owner.hook_out = FALSE;
  85. +/*
  86. +        if (self.enemy.classname == "player")
  87. +                self.enemy.attack_finished = time + 0.1;
  88. +*/
  89. +        BreakChain (self);
  90. +        remove (self);
  91. +};
  92. +
  93. +/**********\
  94. +* HookPull *
  95. +\**********/
  96. +
  97. +void () HookPull =
  98. +{
  99. +        local vector vel, spray;
  100. +        local float v;
  101. +
  102. +    if ((!self.owner.button0 && (self.owner.weapon == IT_HOOK)) ||
  103. +        (self.owner.teleport_time > time ) || self.owner.deadflag ) {
  104. +        HookVanish();
  105. +        return;
  106. +    } else {
  107. +         if (self.enemy.takedamage) {
  108. +            // don't hurt teammates
  109. +            if (self.enemy.classname != "player" || !teamplay ||
  110. +                self.enemy.team != self.owner.team) {
  111. +                sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
  112. +                T_Damage (self.enemy, self, self.owner, 1);
  113. +                makevectors (self.v_angle);
  114. +                spray_x = 100 * crandom();
  115. +                spray_y = 100 * crandom();
  116. +                spray_z = 100 * crandom() + 50;
  117. +                SpawnBlood (self.origin, spray, 20);
  118. +            }
  119. +            if (self.enemy.solid == SOLID_SLIDEBOX) {
  120. +                    self.velocity = '0 0 0';
  121. +                    setorigin (self, self.enemy.origin +
  122. +                            self.enemy.mins +
  123. +                            (self.enemy.size * 0.5));
  124. +            } else {
  125. +                    self.velocity = self.enemy.velocity;
  126. +            }
  127. +        } else {
  128. +                self.velocity = self.enemy.velocity;
  129. +        }
  130. +        if (self.enemy.solid == SOLID_NOT) {
  131. +                HookVanish();
  132. +                return;
  133. +        }
  134. +        makevectors (self.owner.angles);
  135. +        vel = self.origin - ( self.owner.origin + (v_up * 16 *
  136. +                (!self.owner.button2)) + (v_forward * 16));
  137. +        v = vlen (vel);
  138. +        if (v <= 100)
  139. +                vel = normalize(vel) * v * 10;  
  140. +        if ( v > 100 )
  141. +                vel = normalize(vel) * 1000;  
  142. +        self.owner.velocity = vel;
  143. +        self.nextthink = time + 0.1;
  144. +    }
  145. +};
  146. +
  147. +/**************\
  148. +* T_ChainTouch *
  149. +\**************/
  150. +
  151. +void() T_ChainTouch =
  152. +{
  153. +        if (other == self.owner)
  154. +                return;         // don't attach to owner
  155. +
  156. +    if (pointcontents(self.origin) == CONTENT_SKY) {
  157. +                HookVanish();
  158. +                return;
  159. +    }
  160. +
  161. +        if (other.takedamage) {
  162. +                // don't damage teammates
  163. +                if (other.classname != "player" || !teamplay ||
  164. +                    other.team != self.owner.team) {
  165. +                    T_Damage (other, self, self.owner, 10 );
  166. +                    SpawnBlood (self.origin, self.velocity, 10);
  167. +                }
  168. +        } else {
  169. +                self.avelocity = '0 0 0';
  170. +        }
  171. +                
  172. +      sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
  173. +
  174. +        if (!self.owner.button0) {
  175. +                HookVanish();
  176. +                return;
  177. +        } else {
  178. +                if (other.solid == SOLID_SLIDEBOX) {
  179. +                        setorigin (self, other.origin + other.mins +
  180. +                                (other.size * 0.5));
  181. +                        self.velocity = '0 0 0';
  182. +                } else {
  183. +                        self.velocity = other.velocity;
  184. +                }
  185. +                self.weapon = other.nextthink - time;
  186. +                self.enemy = other;
  187. +                self.nextthink = time + 0.1;
  188. +                self.think = HookPull;
  189. +                self.touch = SUB_Null;
  190. +        }
  191. +};
  192. +
  193. +/*************\
  194. +* W_FireChain *
  195. +\*************/
  196. +
  197. +void() W_FireChain =
  198. +{
  199. +        local entity hook;
  200. +
  201. +        self.hook_out = TRUE;
  202. +        hook = spawn ();
  203. +        hook.owner = self;
  204. +        hook.movetype = MOVETYPE_FLY;
  205. +        hook.solid = SOLID_BBOX;
  206. +        
  207. +// set hook speed 
  208. +
  209. +        makevectors (self.v_angle);
  210. +        hook.velocity = aim(self, 1000);
  211. +        hook.velocity = hook.velocity * 1000;
  212. +        hook.angles = vectoangles(hook.velocity);
  213. +        hook.avelocity = '0 0 -500';
  214. +    
  215. +        hook.touch = T_ChainTouch;
  216. +    
  217. +// set hook sound
  218. +        hook.nextthink = time + 5;
  219. +        hook.think = HookVanish;
  220. +
  221. +        setmodel (hook, "progs/v_spike.mdl");
  222. +        setsize (hook, '0 0 0', '0 0 0');     
  223. +        setorigin (hook, self.origin + (v_forward*16) + '0 0 16' );
  224. +
  225. +        hook.goalentity = MakeChain (hook, self, 2);
  226. +};
  227. diff -ur --new-file v106qc/client.qc kalq-src/client.qc
  228. --- v106qc/client.qc    Sun Sep 29 23:29:00 1996
  229. +++ kalq-src/client.qc    Fri Oct 25 00:18:38 1996
  230. @@ -32,12 +32,6 @@
  231.  
  232.  void() SetChangeParms =
  233.  {
  234. -    if (self.health <= 0)
  235. -    {
  236. -        SetNewParms ();
  237. -        return;
  238. -    }
  239. -
  240.  // remove items
  241.      self.items = self.items - (self.items & 
  242.      (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
  243. @@ -69,7 +63,7 @@
  244.      parm4 = 25;
  245.      parm5 = 0;
  246.      parm6 = 0;
  247. -    parm7 = 0;
  248. +    parm6 = 0;
  249.      parm8 = 1;
  250.      parm9 = 0;
  251.  };
  252. @@ -294,17 +288,13 @@
  253.      if (other.classname != "player")
  254.          return;
  255.  
  256. -    if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) && (mapname != "start")))
  257. +    if (cvar("noexit"))
  258.      {
  259.          T_Damage (other, self, self, 50000);
  260.          return;
  261.      }
  262. -
  263. -    if (coop || deathmatch)
  264. -    {
  265. -        bprint (other.netname);
  266. -        bprint (" exited the level\n");
  267. -    }
  268. +    bprint (other.netname);
  269. +    bprint (" exited the level\n");
  270.      
  271.      nextmap = self.map;
  272.  
  273. @@ -407,8 +397,6 @@
  274.  entity() SelectSpawnPoint =
  275.  {
  276.      local    entity spot;
  277. -    local    entity thing;
  278. -    local    float  pcount;
  279.      
  280.  // testinfo_player_start is only found in regioned levels
  281.      spot = find (world, classname, "testplayerstart");
  282. @@ -426,29 +414,11 @@
  283.      }
  284.      else if (deathmatch)
  285.      {
  286. -        spot = lastspawn;
  287. -        while (1)
  288. -        {
  289. -            spot = find(spot, classname, "info_player_deathmatch");
  290. -            if (spot != world)
  291. -            {
  292. -                if (spot == lastspawn)
  293. -                    return lastspawn;
  294. -                pcount = 0;
  295. -                thing = findradius(spot.origin, 32);
  296. -                while(thing)
  297. -                {
  298. -                    if (thing.classname == "player")
  299. -                        pcount = pcount + 1;
  300. -                    thing = thing.chain;
  301. -                }
  302. -                if (pcount == 0)
  303. -                {
  304. -                    lastspawn = spot;
  305. -                    return spot;
  306. -                }
  307. -            }
  308. -        }
  309. +        lastspawn = find(lastspawn, classname, "info_player_deathmatch");
  310. +        if (lastspawn == world)
  311. +            lastspawn = find (lastspawn, classname, "info_player_deathmatch");
  312. +        if (lastspawn != world)
  313. +            return lastspawn;
  314.      }
  315.  
  316.      if (serverflags)
  317. @@ -480,8 +450,6 @@
  318.  {
  319.      local    entity spot;
  320.  
  321. -    spot = SelectSpawnPoint ();
  322. -
  323.      self.classname = "player";
  324.      self.health = 100;
  325.      self.takedamage = DAMAGE_AIM;
  326. @@ -509,9 +477,9 @@
  327.      
  328.      self.deadflag = DEAD_NO;
  329.  // paustime is set by teleporters to keep the player from moving a while
  330. -    self.pausetime = 0;
  331. +        self.pausetime = 0;
  332.      
  333. -//    spot = SelectSpawnPoint ();
  334. +    spot = SelectSpawnPoint ();
  335.  
  336.      self.origin = spot.origin + '0 0 1';
  337.      self.angles = spot.angles;
  338. @@ -594,60 +562,98 @@
  339.  ===============================================================================
  340.  */
  341.  
  342. -/*
  343. -go to the next level for deathmatch
  344. -only called if a time or frag limit has expired
  345. -*/
  346. -void() NextLevel =
  347. +void(entity c) PrintClientScore =
  348.  {
  349. -    local entity o;
  350. +    if (c.frags > -10 && c.frags < 0)
  351. +        bprint (" ");
  352. +    else if (c.frags >= 0)
  353. +    {
  354. +        if (c.frags < 100)
  355. +            bprint (" ");
  356. +        if (c.frags < 10)
  357. +            bprint (" ");
  358. +    }
  359. +    bprint (ftos(c.frags));
  360. +    bprint (" ");
  361. +    bprint (c.netname);
  362. +    bprint ("\n");
  363. +};
  364.  
  365. -    if (mapname == "start")
  366. +void() DumpScore =
  367. +{
  368. +    local entity    e, sort, walk;
  369. +
  370. +    if (world.chain)
  371. +        error ("DumpScore: world.chain is set");
  372. +
  373. +// build a sorted lis
  374. +    e = find(world, classname, "player");
  375. +    sort = world;
  376. +    while (e)
  377.      {
  378. -        if (!cvar("registered"))
  379. -        {
  380. -            mapname = "e1m1";
  381. -        }
  382. -        else if (!(serverflags & 1))
  383. -        {
  384. -            mapname = "e1m1";
  385. -            serverflags = serverflags | 1;
  386. -        }
  387. -        else if (!(serverflags & 2))
  388. -        {
  389. -            mapname = "e2m1";
  390. -            serverflags = serverflags | 2;
  391. -        }
  392. -        else if (!(serverflags & 4))
  393. +        if (!sort)
  394.          {
  395. -            mapname = "e3m1";
  396. -            serverflags = serverflags | 4;
  397. +            sort = e;
  398. +            e.chain = world;
  399.          }
  400. -        else if (!(serverflags & 8))
  401. +        else
  402.          {
  403. -            mapname = "e4m1";
  404. -            serverflags = serverflags - 7;
  405. +            if (e.frags > sort.frags)
  406. +            {
  407. +                e.chain = sort;
  408. +                sort = e;
  409. +            }
  410. +            else
  411. +            {
  412. +                walk = sort;
  413. +                do
  414. +                {
  415. +                    if (!walk.chain)
  416. +                    {
  417. +                        e.chain = world;
  418. +                        walk.chain = e;
  419. +                    }
  420. +                    else if (walk.chain.frags < e.frags)
  421. +                    {
  422. +                        e.chain = walk.chain;
  423. +                        walk.chain = e;
  424. +                    }
  425. +                    else
  426. +                        walk = walk.chain;
  427. +                } while (walk.chain != e);
  428. +            }
  429.          }
  430. -
  431. -        o = spawn();
  432. -        o.map = mapname;
  433. +        
  434. +        e = find(e, classname, "player");
  435.      }
  436. -    else
  437. +
  438. +// print the list
  439. +    
  440. +    bprint ("\n");    
  441. +    while (sort)
  442.      {
  443. -        // find a trigger changelevel
  444. -        o = find(world, classname, "trigger_changelevel");
  445. +        PrintClientScore (sort);
  446. +        sort = sort.chain;
  447. +    }
  448. +    bprint ("\n");
  449. +};
  450.  
  451. -        // go back to start if no trigger_changelevel
  452. -        if (!o)
  453. -        {
  454. -            mapname = "start";
  455. -            o = spawn();
  456. -            o.map = mapname;
  457. -        }
  458. +/*
  459. +go to the next level for deathmatch
  460. +*/
  461. +void() NextLevel =
  462. +{
  463. +    local entity o;
  464. +
  465. +// find a trigger changelevel
  466. +    o = find(world, classname, "trigger_changelevel");
  467. +    if (!o || mapname == "start")
  468. +    {    // go back to same map if no trigger_changelevel
  469. +        o = spawn();
  470. +        o.map = mapname;
  471.      }
  472.  
  473.      nextmap = o.map;
  474. -    gameover = TRUE;
  475.      
  476.      if (o.nextthink < time)
  477.      {
  478. @@ -676,13 +682,31 @@
  479.      
  480.      if (timelimit && time >= timelimit)
  481.      {
  482. -        NextLevel ();
  483. +NextLevel ();
  484. +/*
  485. +        gameover = TRUE;
  486. +        bprint ("\n\n\n==============================\n");
  487. +        bprint ("game exited after ");
  488. +        bprint (ftos(timelimit/60));
  489. +        bprint (" minutes\n");
  490. +        DumpScore ();
  491. +        localcmd ("killserver\n");
  492. +*/
  493.          return;
  494.      }
  495.      
  496.      if (fraglimit && self.frags >= fraglimit)
  497.      {
  498. -        NextLevel ();
  499. +NextLevel ();
  500. +/*
  501. +        gameover = TRUE;
  502. +        bprint ("\n\n\n==============================\n");
  503. +        bprint ("game exited after ");
  504. +        bprint (ftos(self.frags));
  505. +        bprint (" frags\n");
  506. +        DumpScore ();
  507. +        localcmd ("killserver\n");
  508. +*/
  509.          return;
  510.      }    
  511.  };
  512. @@ -726,6 +750,11 @@
  513.  
  514.  void() PlayerJump =
  515.  {
  516. +/*
  517. +        if (self.isfeign)       // experimental
  518. +                return;
  519. +//      Can jump as a Corpse (while Feigning).
  520. +*/
  521.      local vector start, end;
  522.      
  523.      if (self.flags & FL_WATERJUMP)
  524. @@ -788,7 +817,8 @@
  525.  
  526.      if (self.waterlevel != 3)
  527.      {
  528. -        if (self.air_finished < time)
  529. +                if (self.isfeign) return;
  530. +            if (self.air_finished < time)
  531.              sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
  532.          else if (self.air_finished < time + 9)
  533.              sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
  534. @@ -797,7 +827,8 @@
  535.      }
  536.      else if (self.air_finished < time)
  537.      {    // drown!
  538. -        if (self.pain_finished < time)
  539. +                if (self.isfeign) return;
  540. +                if (self.pain_finished < time)
  541.          {
  542.              self.dmg = self.dmg + 2;
  543.              if (self.dmg > 15)
  544. @@ -832,7 +863,8 @@
  545.      }
  546.      else if (self.watertype == CONTENT_SLIME)
  547.      {    // do damage
  548. -        if (self.dmgtime < time && self.radsuit_finished < time)
  549. +                if (self.isfeign) return;
  550. +                if (self.dmgtime < time && self.radsuit_finished < time)
  551.          {
  552.              self.dmgtime = time + 1;
  553.              T_Damage (self, world, world, 4*self.waterlevel);
  554. @@ -849,7 +881,8 @@
  555.          if (self.watertype == CONTENT_WATER)
  556.              sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
  557.          if (self.watertype == CONTENT_SLIME)
  558. -            sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
  559. +                        if (self.isfeign) return;
  560. +                        sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
  561.  
  562.          self.flags = self.flags + FL_INWATER;
  563.          self.dmgtime = 0;
  564. @@ -937,12 +970,6 @@
  565.  // teleporters can force a non-moving pause time    
  566.      if (time < self.pausetime)
  567.          self.velocity = '0 0 0';
  568. -
  569. -    if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
  570. -    {
  571. -        self.weapon = W_BestWeapon ();
  572. -        W_SetCurrentAmmo ();
  573. -    }
  574.  };
  575.      
  576.  /*
  577. @@ -1236,25 +1263,12 @@
  578.                      bprint (" discharges into the water.\n");
  579.                      return;
  580.                  }
  581. -                if (targ.weapon == IT_GRENADE_LAUNCHER)
  582. +                if (targ.weapon == 16)
  583.                      bprint (" tries to put the pin back in\n");
  584. -                else
  585. +                else if (rnum)
  586.                      bprint (" becomes bored with life\n");
  587. -                return;
  588. -            }
  589. -            else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
  590. -            {
  591. -                if (rnum < 0.25)
  592. -                    deathstring = " mows down a teammate\n";
  593. -                else if (rnum < 0.50)
  594. -                    deathstring = " checks his glasses\n";
  595. -                else if (rnum < 0.75)
  596. -                    deathstring = " gets a frag for the other team\n";
  597.                  else
  598. -                    deathstring = " loses another friend\n";
  599. -                bprint (attacker.netname);
  600. -                bprint (deathstring);
  601. -                attacker.frags = attacker.frags - 1;
  602. +                    bprint (" checks if his weapon is loaded\n");
  603.                  return;
  604.              }
  605.              else
  606. @@ -1324,10 +1338,40 @@
  607.          }
  608.          else
  609.          {
  610. -            targ.frags = targ.frags - 1;
  611. +            targ.frags = targ.frags - 1;        // killed self
  612. +            rnum = targ.watertype;
  613. +
  614.              bprint (targ.netname);
  615. +            if (rnum == -3)
  616. +            {
  617. +                if (random() < 0.5)
  618. +                    bprint (" sleeps with the fishes\n");
  619. +                else
  620. +                    bprint (" sucks it down\n");
  621. +                return;
  622. +            }
  623. +            else if (rnum == -4)
  624. +            {
  625. +                if (random() < 0.5)
  626. +                    bprint (" gulped a load of slime\n");
  627. +                else
  628. +                    bprint (" can't exist on slime alone\n");
  629. +                return;
  630. +            }
  631. +            else if (rnum == -5)
  632. +            {
  633. +                if (targ.health < -15)
  634. +                {
  635. +                    bprint (" burst into flames\n");
  636. +                    return;
  637. +                }
  638. +                if (random() < 0.5)
  639. +                    bprint (" turned into hot slag\n");
  640. +                else
  641. +                    bprint (" visits the Volcano God\n");
  642. +                return;
  643. +            }
  644.  
  645. -            // killed by a montser?
  646.              if (attacker.flags & FL_MONSTER)
  647.              {
  648.                  if (attacker.classname == "monster_army")
  649. @@ -1365,8 +1409,6 @@
  650.  
  651.                  return;
  652.              }
  653. -
  654. -            // tricks and traps
  655.              if (attacker.classname == "explo_box")
  656.              {
  657.                  bprint (" blew up\n");
  658. @@ -1377,6 +1419,12 @@
  659.                  bprint (" was squished\n");
  660.                  return;
  661.              }
  662. +            if (targ.deathtype == "falling")
  663. +            {
  664. +                targ.deathtype = "";
  665. +                bprint (" fell to his death\n");
  666. +                return;
  667. +            }
  668.              if (attacker.classname == "trap_shooter" || attacker.classname == "trap_spikeshooter")
  669.              {
  670.                  bprint (" was spiked\n");
  671. @@ -1393,47 +1441,6 @@
  672.                  return;
  673.              }
  674.  
  675. -            // in-water deaths
  676. -            rnum = targ.watertype;
  677. -            if (rnum == -3)
  678. -            {
  679. -                if (random() < 0.5)
  680. -                    bprint (" sleeps with the fishes\n");
  681. -                else
  682. -                    bprint (" sucks it down\n");
  683. -                return;
  684. -            }
  685. -            else if (rnum == -4)
  686. -            {
  687. -                if (random() < 0.5)
  688. -                    bprint (" gulped a load of slime\n");
  689. -                else
  690. -                    bprint (" can't exist on slime alone\n");
  691. -                return;
  692. -            }
  693. -            else if (rnum == -5)
  694. -            {
  695. -                if (targ.health < -15)
  696. -                {
  697. -                    bprint (" burst into flames\n");
  698. -                    return;
  699. -                }
  700. -                if (random() < 0.5)
  701. -                    bprint (" turned into hot slag\n");
  702. -                else
  703. -                    bprint (" visits the Volcano God\n");
  704. -                return;
  705. -            }
  706. -
  707. -            // fell to their death?
  708. -            if (targ.deathtype == "falling")
  709. -            {
  710. -                targ.deathtype = "";
  711. -                bprint (" fell to his death\n");
  712. -                return;
  713. -            }
  714. -
  715. -            // hell if I know; he's just dead!!!
  716.              bprint (" died\n");
  717.          }
  718.      }
  719. diff -ur --new-file v106qc/defs.qc kalq-src/defs.qc
  720. --- v106qc/defs.qc    Thu Sep 26 11:15:38 1996
  721. +++ kalq-src/defs.qc    Fri Oct 25 05:49:58 1996
  722. @@ -89,6 +89,13 @@
  723.  void        end_sys_globals;        // flag for structure dumping
  724.  //================================================
  725.  
  726. +// MODIFIED: Wisp global constants
  727. +
  728. +float           WISP_HUNT       =0;
  729. +float           WISP_APPROACH   =1;
  730. +float           WISP_HALT       =2;
  731. +float           WISP_ATTACK     =3;
  732. +
  733.  /*
  734.  ==============================================================================
  735.  
  736. @@ -211,6 +218,15 @@
  737.  void        end_sys_fields;            // flag for structure dumping
  738.  //================================================
  739.  
  740. +// MODIFIED: Fields for Wisp
  741. +
  742. +.entity         wisp;
  743. +.float          wisp_flag;
  744. +.float          wisp_state;
  745. +.float          wisp_view;
  746. +.vector         wisp_porg;
  747. +.float          wisp_stuck;
  748. +
  749.  /*
  750.  ==============================================================================
  751.  
  752. @@ -283,6 +299,7 @@
  753.  
  754.  // items
  755.  float    IT_AXE                    = 4096;
  756. +float   IT_HOOK                                 = 4198400;
  757.  float    IT_SHOTGUN                = 1;
  758.  float    IT_SUPER_SHOTGUN        = 2;
  759.  float    IT_NAILGUN                = 4;
  760. @@ -291,6 +308,10 @@
  761.  float    IT_ROCKET_LAUNCHER        = 32;
  762.  float    IT_LIGHTNING            = 64;
  763.  float    IT_EXTRA_WEAPON            = 128;
  764. +float    IT_FIREWALL            = 8388608;
  765. +float    IT_BOMB                = 16777216;
  766. +float    IT_GIBGUN            = 33554432;
  767. +float   IT_TRACTOR_BEAM                 = 128;
  768.  
  769.  float    IT_SHELLS                = 256;
  770.  float    IT_NAILS                = 512;
  771. @@ -461,6 +482,8 @@
  772.  
  773.  .float         attack_finished;
  774.  .float        pain_finished;
  775. +.float          hook_out;
  776. +
  777.  
  778.  .float        invincible_finished;
  779.  .float        invisible_finished;
  780. @@ -509,6 +532,7 @@
  781.  //
  782.  .float         pausetime;
  783.  .entity     movetarget;
  784. +.float          hooked;
  785.  
  786.  
  787.  //
  788. @@ -690,4 +714,9 @@
  789.  
  790.  float(entity targ, entity inflictor) CanDamage;
  791.  
  792. +
  793. +.entity teledrop_dest;
  794. +.float tele_dropped;
  795. +.entity telebomb;
  796. +.float telebomb_dropped;
  797.  
  798. diff -ur --new-file v106qc/feign.qc kalq-src/feign.qc
  799. --- v106qc/feign.qc    Thu Jan  1 00:00:00 1970
  800. +++ kalq-src/feign.qc    Wed Oct 23 00:55:56 1996
  801. @@ -0,0 +1,156 @@
  802. +// This is my poor attempt to add something useful 
  803. +
  804. +// Globals
  805. +
  806. +.float isfeign;
  807. +.string oldweaponmodel;         // change to local?
  808. +.float oldweapon;               // change to local?
  809. +
  810. +// Frames
  811. +//
  812. +//      I had to re-init them all to be able to call them.
  813. +// If I had this function in player.qc, this wouldn't be
  814. +// necessary, but then it would be less modular.
  815. +
  816. +$cd /raid/quake/id1/models/player_4
  817. +$origin 0 -6 24
  818. +$base base        
  819. +$skin skin
  820. +
  821. +$frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
  822. +$frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
  823. +$frame stand1 stand2 stand3 stand4 stand5
  824. +$frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
  825. +$frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
  826. +$frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
  827. +$frame pain1 pain2 pain3 pain4 pain5 pain6
  828. +$frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
  829. +$frame axdeth7 axdeth8 axdeth9
  830. +$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
  831. +$frame deatha9 deatha10 deatha11
  832. +$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
  833. +$frame deathb9
  834. +$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
  835. +$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
  836. +$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
  837. +$frame deathd8 deathd9
  838. +$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
  839. +$frame deathe8 deathe9
  840. +$frame nailatt1 nailatt2
  841. +$frame light1 light2
  842. +$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
  843. +$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
  844. +$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
  845. +$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
  846. +$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
  847. +$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
  848. +
  849. +
  850. +// Falling down animation.  Any would have done.
  851. +
  852. +void()  player_feigna1    =       [       $deatha1,       player_feigna2    ] {};
  853. +void()  player_feigna2    =       [       $deatha2,       player_feigna3    ] {};
  854. +void()  player_feigna3    =       [       $deatha3,       player_feigna4    ] {};
  855. +void()  player_feigna4    =       [       $deatha4,       player_feigna5    ] {};
  856. +void()  player_feigna5    =       [       $deatha5,       player_feigna6    ] {};
  857. +void()  player_feigna6    =       [       $deatha6,       player_feigna7    ] {};
  858. +void()  player_feigna7    =       [       $deatha7,       player_feigna8    ] {};
  859. +void()  player_feigna8    =       [       $deatha8,       player_feigna9    ] {};
  860. +void()  player_feigna9    =       [       $deatha9,       player_feigna10   ] {};
  861. +void()  player_feigna10   =       [       $deatha10,      player_feigna11   ] {};
  862. +void()  player_feigna11   =       [       $deatha11,      player_feigna11   ] {};
  863. +
  864. +
  865. +// Standing up animation.  This one looks the best.
  866. +
  867. +void()  player_upa1    =       [       $deathd9,        player_upa2    ] {};
  868. +void()  player_upa2    =       [       $deathd8,        player_upa3    ] {};
  869. +void()  player_upa3    =       [       $deathd7,        player_upa4    ] {};
  870. +void()  player_upa4    =       [       $deathd6,        player_upa5    ] {};
  871. +void()  player_upa5    =       [       $deathd5,        player_upa6    ] {};
  872. +void()  player_upa6    =       [       $deathd4,        player_upa7    ] {};
  873. +void()  player_upa7    =       [       $deathd3,        player_upa8    ] {};
  874. +void()  player_upa8    =       [       $deathd2,        player_upa9    ] {};
  875. +void()  player_upa9    =       [       $deathd1,        player_upa9    ] {player_stand1 ();};
  876. +
  877. +
  878. +//      I had to make new backpack routines so that you wouldn't give up 
  879. +// your ammo, pick it up while you're throwing it, and have a neat message.
  880. +
  881. +void() FakeBackpackTouch =
  882. +{
  883. +        if (self.isfeign) return;
  884. +
  885. +        if (other.classname != "player")        // Monsters won't pick up
  886. +        return;
  887. +        if (other.health <= 0)                  // Dead people won't pick up
  888. +        return;
  889. +//      if ( (self.owner == other) && ( (self.nextthink - time) > 99 ) )        // The thrower won't pick up
  890. +                return;                                                         // unless 20 sec has passed.
  891. +
  892. +        sprint (other, "Hmmmm, empty...\n");
  893. +        sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);    // backpack touch sound
  894. +        stuffcmd (other, "bf\n");       // flashes the screen
  895. +    remove(self);
  896. +    
  897. +};
  898. +
  899. +
  900. +void() FakeBackpack =
  901. +{
  902. +    local entity    item;
  903. +
  904. +    item = spawn();
  905. +        item.owner = self;
  906. +        item.origin = self.origin - '0 0 24';
  907. +    item.velocity_z = 300;
  908. +    item.velocity_x = -100 + (random() * 200);
  909. +    item.velocity_y = -100 + (random() * 200);
  910. +    item.flags = FL_ITEM;
  911. +    item.solid = SOLID_TRIGGER;
  912. +        item.movetype = MOVETYPE_TOSS;
  913. +    setmodel (item, "progs/backpack.mdl");
  914. +    setsize (item, '-16 -16 0', '16 16 56');
  915. +        item.touch = FakeBackpackTouch;
  916. +    item.nextthink = time + 120;    // remove after 2 minutes
  917. +    item.think = SUB_Remove;
  918. +};
  919. +
  920. +void() feign =
  921. +{
  922. +        if (!self.isfeign)              // If not already, feign death
  923. +        {
  924. +                player_feigna1 ();      // death animation
  925. +                FakeBackpack();         // throw fake backpack
  926. +//              setsize (self , '-16 -16 -4' , '16 16 4');      // change bounding bos so you're shorter
  927. +                self.view_ofs = '0 0 2';        // put view near ground
  928. +                DeathSound();           // yell like you're dying
  929. +                self.modelindex = modelindex_eyes;
  930. +/*
  931. +                self.oldweapon = self.weapon;
  932. +                self.weapon = 0;
  933. +                self.oldweaponmodel = self.weaponmodel;
  934. +                self.weaponmodel = "";
  935. +*/
  936. +//              self.movetype = MOVETYPE_TOSS;
  937. +                self.movetype = MOVETYPE_WALK;
  938. +                self.isfeign = TRUE;
  939. +        }
  940. +
  941. +        else                    // otherwise, get up
  942. +
  943. +        {
  944. +                self.movetype = MOVETYPE_WALK;
  945. +//              setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
  946. +                self.view_ofs = '0 0 22';
  947. +                self.model = "progs/player.mdl";
  948. +/*
  949. +                self.weaponmodel = self.oldweaponmodel;
  950. +                self.weapon = self.oldweapon;
  951. +                self.oldweapon = 0;
  952. +*/
  953. +                self.isfeign = FALSE;
  954. +                player_upa1();
  955. +        }
  956. +};
  957. +
  958. diff -ur --new-file v106qc/items.qc kalq-src/items.qc
  959. --- v106qc/items.qc    Thu Sep 26 11:15:38 1996
  960. +++ kalq-src/items.qc    Tue Oct 22 15:02:16 1996
  961. @@ -2,9 +2,36 @@
  962.  /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  963.  BE .8 .3 .4 IN COLOR */
  964.  
  965. +entity item_to_exchange;
  966. +void(float exchange) SUB_Withdraw = {
  967. +    local vector temp;
  968. +
  969. +    if(exchange) {
  970. +        if(item_to_exchange) {
  971. +//            dprint(self.classname);
  972. +//            dprint(" moved from ");
  973. +//            dprint(vtos(self.origin));
  974. +//            dprint(" to ");
  975. +//            dprint(vtos(spare_item_origin));
  976. +//            dprint("\n");
  977. +            temp=self.origin;
  978. +            self.origin=item_to_exchange.origin;
  979. +            item_to_exchange.origin=temp;
  980. +            item_to_exchange=world;
  981. +        } else {
  982. +            item_to_exchange=self;
  983. +        }
  984. +    }
  985. +
  986. +    self.model = string_null;
  987. +    self.solid = SOLID_NOT;
  988. +};
  989.  
  990.  void() SUB_regen =
  991.  {
  992. +    if(item_to_exchange == self) { // Didn't get exchanged
  993. +        item_to_exchange = world;
  994. +    }
  995.      self.model = self.mdl;        // restore original model
  996.      self.solid = SOLID_TRIGGER;    // allow it to be touched again
  997.      sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  998. @@ -178,8 +205,7 @@
  999.  
  1000.      stuffcmd (other, "bf\n");
  1001.      
  1002. -    self.model = string_null;
  1003. -    self.solid = SOLID_NOT;
  1004. +    SUB_Withdraw(1);
  1005.  
  1006.      // Megahealth = rot down the player's super health
  1007.      if (self.healtype == 2)
  1008. @@ -269,8 +295,7 @@
  1009.      other.armorvalue = value;
  1010.      other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  1011.  
  1012. -    self.solid = SOLID_NOT;
  1013. -    self.model = string_null;
  1014. +    SUB_Withdraw(1);
  1015.      if (deathmatch == 1)
  1016.          self.nextthink = time + 20;
  1017.      self.think = SUB_regen;
  1018. @@ -489,8 +514,8 @@
  1019.          return;
  1020.  
  1021.  // remove it in single player, or setup for respawning in deathmatch
  1022. -    self.model = string_null;
  1023. -    self.solid = SOLID_NOT;
  1024. +    
  1025. +    SUB_Withdraw(1);
  1026.      if (deathmatch == 1)
  1027.          self.nextthink = time + 30;
  1028.      self.think = SUB_regen;
  1029. @@ -638,7 +663,7 @@
  1030.  //    cells
  1031.      if (self.weapon == 4)
  1032.      {
  1033. -        if (other.ammo_cells >= 100)
  1034. +        if (other.ammo_cells >= 200)
  1035.              return;
  1036.          other.ammo_cells = other.ammo_cells + self.aflag;
  1037.      }
  1038. @@ -670,10 +695,11 @@
  1039.      self = stemp;
  1040.  
  1041.  // remove it in single player, or setup for respawning in deathmatch
  1042. -    self.model = string_null;
  1043. -    self.solid = SOLID_NOT;
  1044. +
  1045. +    SUB_Withdraw(1);
  1046.      if (deathmatch == 1)
  1047.          self.nextthink = time + 30;
  1048. +    
  1049.      self.think = SUB_regen;
  1050.  
  1051.      activator = other;
  1052. @@ -697,15 +723,16 @@
  1053.          precache_model ("maps/b_shell1.bsp");
  1054.          setmodel (self, "maps/b_shell1.bsp");
  1055.          self.aflag = 40;
  1056. +        self.netname = "box of shells";
  1057.      }
  1058.      else
  1059.      {
  1060.          precache_model ("maps/b_shell0.bsp");
  1061.          setmodel (self, "maps/b_shell0.bsp");
  1062.          self.aflag = 20;
  1063. +        self.netname = "shells";
  1064.      }
  1065.      self.weapon = 1;
  1066. -    self.netname = "shells";
  1067.      setsize (self, '0 0 0', '32 32 56');
  1068.      StartItem ();
  1069.  };
  1070. @@ -722,15 +749,16 @@
  1071.          precache_model ("maps/b_nail1.bsp");
  1072.          setmodel (self, "maps/b_nail1.bsp");
  1073.          self.aflag = 50;
  1074. +        self.netname = "crate of nails";
  1075.      }
  1076.      else
  1077.      {
  1078.          precache_model ("maps/b_nail0.bsp");
  1079.          setmodel (self, "maps/b_nail0.bsp");
  1080.          self.aflag = 25;
  1081. +        self.netname = "nails";
  1082.      }
  1083.      self.weapon = 2;
  1084. -    self.netname = "nails";
  1085.      setsize (self, '0 0 0', '32 32 56');
  1086.      StartItem ();
  1087.  };
  1088. @@ -747,15 +775,16 @@
  1089.          precache_model ("maps/b_rock1.bsp");
  1090.          setmodel (self, "maps/b_rock1.bsp");
  1091.          self.aflag = 10;
  1092. +        self.netname = "box of rockets";
  1093.      }
  1094.      else
  1095.      {
  1096.          precache_model ("maps/b_rock0.bsp");
  1097.          setmodel (self, "maps/b_rock0.bsp");
  1098.          self.aflag = 5;
  1099. +        self.netname = "rockets";
  1100.      }
  1101.      self.weapon = 3;
  1102. -    self.netname = "rockets";
  1103.      setsize (self, '0 0 0', '32 32 56');
  1104.      StartItem ();
  1105.  };
  1106. @@ -773,15 +802,16 @@
  1107.          precache_model ("maps/b_batt1.bsp");
  1108.          setmodel (self, "maps/b_batt1.bsp");
  1109.          self.aflag = 12;
  1110. +        self.netname = "battery pack";
  1111.      }
  1112.      else
  1113.      {
  1114.          precache_model ("maps/b_batt0.bsp");
  1115.          setmodel (self, "maps/b_batt0.bsp");
  1116.          self.aflag = 6;
  1117. +        self.netname = "cells";
  1118.      }
  1119.      self.weapon = 4;
  1120. -    self.netname = "cells";
  1121.      setsize (self, '0 0 0', '32 32 56');
  1122.      StartItem ();
  1123.  };
  1124. @@ -888,8 +918,7 @@
  1125.  
  1126.      if (!coop)
  1127.      {    
  1128. -        self.solid = SOLID_NOT;
  1129. -        self.model = string_null;
  1130. +        SUB_Withdraw(1);
  1131.      }
  1132.  
  1133.      activator = other;
  1134. @@ -1016,8 +1045,7 @@
  1135.  
  1136.      sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1137.      stuffcmd (other, "bf\n");
  1138. -    self.solid = SOLID_NOT;
  1139. -    self.model = string_null;
  1140. +    SUB_Withdraw(1);
  1141.      serverflags = serverflags | (self.spawnflags & 15);
  1142.      self.classname = "";        // so rune doors won't find it
  1143.      
  1144. @@ -1104,33 +1132,35 @@
  1145.  
  1146.      sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1147.      stuffcmd (other, "bf\n");
  1148. -    self.solid = SOLID_NOT;
  1149.      other.items = other.items | self.items;
  1150. -    self.model = string_null;
  1151.  
  1152.  // do the apropriate action
  1153.      if (self.classname == "item_artifact_envirosuit")
  1154.      {
  1155.          other.rad_time = 1;
  1156.          other.radsuit_finished = time + 30;
  1157. +        SUB_Withdraw(0); // Leave envirosuit, it's there for a reason
  1158.      }
  1159.      
  1160.      if (self.classname == "item_artifact_invulnerability")
  1161.      {
  1162.          other.invincible_time = 1;
  1163.          other.invincible_finished = time + 30;
  1164. +        SUB_Withdraw(1);
  1165.      }
  1166.      
  1167.      if (self.classname == "item_artifact_invisibility")
  1168.      {
  1169.          other.invisible_time = 1;
  1170.          other.invisible_finished = time + 30;
  1171. +        SUB_Withdraw(1);
  1172.      }
  1173.  
  1174.      if (self.classname == "item_artifact_super_damage")
  1175.      {
  1176.          other.super_time = 1;
  1177.          other.super_damage_finished = time + 30;
  1178. +        SUB_Withdraw(1);
  1179.      }    
  1180.  
  1181.      activator = other;
  1182. @@ -1229,26 +1259,14 @@
  1183.  void() BackpackTouch =
  1184.  {
  1185.      local string    s;
  1186. -    local    float    best, old, new;
  1187. +    local    float    best;
  1188.      local        entity    stemp;
  1189. -    local    float    acount;
  1190.      
  1191.      if (other.classname != "player")
  1192.          return;
  1193.      if (other.health <= 0)
  1194.          return;
  1195. -
  1196. -    acount = 0;
  1197. -    sprint (other, "You get ");
  1198. -
  1199. -    if (self.items)
  1200. -        if ((other.items & self.items) == 0)
  1201. -        {
  1202. -            acount = 1;
  1203. -            sprint (other, "the ");
  1204. -            sprint (other, self.netname);
  1205. -        }
  1206. -
  1207. +        
  1208.  // if the player was using his best weapon, change up to the new one if better        
  1209.      stemp = self;
  1210.      self = other;
  1211. @@ -1261,49 +1279,35 @@
  1212.      other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1213.      other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1214.  
  1215. -    new = self.items;
  1216. -    if (!new)
  1217. -        new = other.weapon;
  1218. -    old = other.items;
  1219. -    other.items = other.items | new;
  1220. +    other.items = other.items | self.items;
  1221.      
  1222.      bound_other_ammo ();
  1223.  
  1224. +    sprint (other, "You get ");
  1225. +
  1226.      if (self.ammo_shells)
  1227.      {
  1228. -        if (acount)
  1229. -            sprint(other, ", ");
  1230. -        acount = 1;
  1231.          s = ftos(self.ammo_shells);
  1232.          sprint (other, s);
  1233. -        sprint (other, " shells");
  1234. +        sprint (other, " shells  ");
  1235.      }
  1236.      if (self.ammo_nails)
  1237.      {
  1238. -        if (acount)
  1239. -            sprint(other, ", ");
  1240. -        acount = 1;
  1241.          s = ftos(self.ammo_nails);
  1242.          sprint (other, s);
  1243. -        sprint (other, " nails");
  1244. +        sprint (other, " nails ");
  1245.      }
  1246.      if (self.ammo_rockets)
  1247.      {
  1248. -        if (acount)
  1249. -            sprint(other, ", ");
  1250. -        acount = 1;
  1251.          s = ftos(self.ammo_rockets);
  1252.          sprint (other, s);
  1253. -        sprint (other, " rockets");
  1254. +        sprint (other, " rockets  ");
  1255.      }
  1256.      if (self.ammo_cells)
  1257.      {
  1258. -        if (acount)
  1259. -            sprint(other, ", ");
  1260. -        acount = 1;
  1261.          s = ftos(self.ammo_cells);
  1262.          sprint (other, s);
  1263. -        sprint (other, " cells");
  1264. +        sprint (other, " cells  ");
  1265.      }
  1266.      
  1267.      sprint (other, "\n");
  1268. @@ -1311,16 +1315,19 @@
  1269.      sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1270.      stuffcmd (other, "bf\n");
  1271.  
  1272. -// remove the backpack, change self to the player
  1273. +// change to a better weapon if appropriate
  1274. +    if ( other.weapon == best )
  1275. +    {
  1276. +        stemp = self;
  1277. +        self = other;
  1278. +        self.weapon = W_BestWeapon();
  1279. +        self = stemp;
  1280. +    }
  1281. +
  1282. +    
  1283.      remove(self);
  1284. +    
  1285.      self = other;
  1286. -
  1287. -// change to the weapon
  1288. -    if (!deathmatch)
  1289. -        self.weapon = new;
  1290. -    else
  1291. -        Deathmatch_Weapon (old, new);
  1292. -
  1293.      W_SetCurrentAmmo ();
  1294.  };
  1295.  
  1296. @@ -1340,25 +1347,8 @@
  1297.      item.origin = self.origin - '0 0 24';
  1298.      
  1299.      item.items = self.weapon;
  1300. -    if (item.items == IT_AXE)
  1301. -        item.netname = "Axe";
  1302. -    else if (item.items == IT_SHOTGUN)
  1303. -        item.netname = "Shotgun";
  1304. -    else if (item.items == IT_SUPER_SHOTGUN)
  1305. -        item.netname = "Double-barrelled Shotgun";
  1306. -    else if (item.items == IT_NAILGUN)
  1307. -        item.netname = "Nailgun";
  1308. -    else if (item.items == IT_SUPER_NAILGUN)
  1309. -        item.netname = "Super Nailgun";
  1310. -    else if (item.items == IT_GRENADE_LAUNCHER)
  1311. -        item.netname = "Grenade Launcher";
  1312. -    else if (item.items == IT_ROCKET_LAUNCHER)
  1313. -        item.netname = "Rocket Launcher";
  1314. -    else if (item.items == IT_LIGHTNING)
  1315. -        item.netname = "Thunderbolt";
  1316. -    else
  1317. -        item.netname = "";
  1318. -
  1319. +    if ((item.items == IT_FIREWALL) || (item.items == IT_BOMB))     item.items=IT_GRENADE_LAUNCHER;
  1320. +    if (item.items == IT_GIBGUN) item.items=IT_ROCKET_LAUNCHER;
  1321.      item.ammo_shells = self.ammo_shells;
  1322.      item.ammo_nails = self.ammo_nails;
  1323.      item.ammo_rockets = self.ammo_rockets;
  1324. diff -ur --new-file v106qc/player.qc kalq-src/player.qc
  1325. --- v106qc/player.qc    Thu Sep 26 11:15:40 1996
  1326. +++ kalq-src/player.qc    Fri Oct 25 01:39:36 1996
  1327. @@ -1,6 +1,9 @@
  1328.  
  1329.  void() bubble_bob;
  1330. -
  1331. +void() W_FireChain;
  1332. +void() player_chain5;
  1333. +void() player_chain4;
  1334. +                   
  1335.  /*
  1336.  ==============================================================================
  1337.  
  1338. @@ -9,7 +12,7 @@
  1339.  ==============================================================================
  1340.  */
  1341.  
  1342. -$cd id1/models/player_4
  1343. +$cd /raid/quake/id1/models/player_4
  1344.  $origin 0 -6 24
  1345.  $base base        
  1346.  $skin skin
  1347. @@ -167,6 +170,42 @@
  1348.  void()    player_axed3 =    [$axattd3, player_axed4    ] {self.weaponframe=7;W_FireAxe();};
  1349.  void()    player_axed4 =    [$axattd4, player_run    ] {self.weaponframe=8;};
  1350.  
  1351. +void()  player_chain1=  [$axattd1, player_chain2 ] {self.weaponframe=2;};
  1352. +void()  player_chain2=  [$axattd2, player_chain3 ] {self.weaponframe=3;W_FireChain();};
  1353. +
  1354. +void()  player_chain3=  [$axattd3, player_chain3 ]
  1355. +{
  1356. +        self.weaponframe=3;
  1357. +        if (!self.hook_out)
  1358. +        {
  1359. +                player_chain5();
  1360. +                return;
  1361. +        }
  1362. +        if (vlen(self.velocity) >= 750)
  1363. +        {
  1364. +                player_chain4();
  1365. +                return;
  1366. +        }
  1367. +};
  1368. +
  1369. +void() player_chain4=  [$deathc4, player_chain4 ]
  1370. +{
  1371. +        self.weaponframe=4;
  1372. +        if (!self.hook_out)
  1373. +        {
  1374. +                player_chain5();
  1375. +                return;
  1376. +        }
  1377. +        if (vlen(self.velocity) < 750)
  1378. +        {
  1379. +                player_chain3();
  1380. +                return;
  1381. +        }
  1382. +};
  1383. +
  1384. +void()  player_chain5=  [$axattd4, player_run    ] {self.weaponframe=5;};
  1385. +
  1386. +
  1387.  
  1388.  //============================================================================
  1389.  
  1390. @@ -342,6 +381,9 @@
  1391.      if (self.invisible_finished > time)
  1392.          return;        // eyes don't have pain frames
  1393.  
  1394. +        if (self.isfeign)       // experimental
  1395. +                return;
  1396. +
  1397.      if (self.weapon == IT_AXE)
  1398.          player_axpain1 ();
  1399.      else
  1400. @@ -524,25 +566,28 @@
  1401.  void() PlayerDie =
  1402.  {
  1403.      local    float    i;
  1404. -    
  1405. -    self.items = self.items - (self.items & IT_INVISIBILITY);
  1406. -    self.invisible_finished = 0;    // don't die as eyes
  1407. -    self.invincible_finished = 0;
  1408. -    self.super_damage_finished = 0;
  1409. -    self.radsuit_finished = 0;
  1410. -    self.modelindex = modelindex_player;    // don't use eyes
  1411.  
  1412. -    if (deathmatch || coop)
  1413. -        DropBackpack();
  1414. -    
  1415. -    self.weaponmodel="";
  1416. -    self.view_ofs = '0 0 -8';
  1417. -    self.deadflag = DEAD_DYING;
  1418. -    self.solid = SOLID_NOT;
  1419. -    self.flags = self.flags - (self.flags & FL_ONGROUND);
  1420. -    self.movetype = MOVETYPE_TOSS;
  1421. -    if (self.velocity_z < 10)
  1422. -        self.velocity_z = self.velocity_z + random()*300;
  1423. +        if (self.isfeign)               // experimental
  1424. +                feign;               // don't die while down
  1425. +
  1426. +        self.items = self.items - (self.items & IT_INVISIBILITY);
  1427. +        self.invisible_finished = 0;    // don't die as eyes
  1428. +//      self.tele_dropped = 0;
  1429. +        self.invincible_finished = 0;
  1430. +        self.super_damage_finished = 0;
  1431. +        self.radsuit_finished = 0;
  1432. +        self.modelindex = modelindex_player;
  1433. +
  1434. +        if (deathmatch || coop)
  1435. +              DropBackpack();
  1436. +        self.weaponmodel="";
  1437. +        self.view_ofs = '0 0 -8';
  1438. +        self.deadflag = DEAD_DYING;
  1439. +        self.solid = SOLID_NOT;
  1440. +        self.flags = self.flags - (self.flags & FL_ONGROUND);
  1441. +        self.movetype = MOVETYPE_TOSS;
  1442. +        if (self.velocity_z < 10)
  1443. +              self.velocity_z = self.velocity_z + random()*300;
  1444.  
  1445.      if (self.health < -40)
  1446.      {
  1447. diff -ur --new-file v106qc/progdefs.h kalq-src/progdefs.h
  1448. --- v106qc/progdefs.h    Thu Jan  1 00:00:00 1970
  1449. +++ kalq-src/progdefs.h    Fri Oct 25 06:02:04 1996
  1450. @@ -0,0 +1,143 @@
  1451. +
  1452. +/* file generated by qcc, do not modify */
  1453. +
  1454. +typedef struct
  1455. +{    int    pad[28];
  1456. +    int    self;
  1457. +    int    other;
  1458. +    int    world;
  1459. +    float    time;
  1460. +    float    frametime;
  1461. +    float    force_retouch;
  1462. +    string_t    mapname;
  1463. +    float    deathmatch;
  1464. +    float    coop;
  1465. +    float    teamplay;
  1466. +    float    serverflags;
  1467. +    float    total_secrets;
  1468. +    float    total_monsters;
  1469. +    float    found_secrets;
  1470. +    float    killed_monsters;
  1471. +    float    parm1;
  1472. +    float    parm2;
  1473. +    float    parm3;
  1474. +    float    parm4;
  1475. +    float    parm5;
  1476. +    float    parm6;
  1477. +    float    parm7;
  1478. +    float    parm8;
  1479. +    float    parm9;
  1480. +    float    parm10;
  1481. +    float    parm11;
  1482. +    float    parm12;
  1483. +    float    parm13;
  1484. +    float    parm14;
  1485. +    float    parm15;
  1486. +    float    parm16;
  1487. +    vec3_t    v_forward;
  1488. +    vec3_t    v_up;
  1489. +    vec3_t    v_right;
  1490. +    float    trace_allsolid;
  1491. +    float    trace_startsolid;
  1492. +    float    trace_fraction;
  1493. +    vec3_t    trace_endpos;
  1494. +    vec3_t    trace_plane_normal;
  1495. +    float    trace_plane_dist;
  1496. +    int    trace_ent;
  1497. +    float    trace_inopen;
  1498. +    float    trace_inwater;
  1499. +    int    msg_entity;
  1500. +    func_t    main;
  1501. +    func_t    StartFrame;
  1502. +    func_t    PlayerPreThink;
  1503. +    func_t    PlayerPostThink;
  1504. +    func_t    ClientKill;
  1505. +    func_t    ClientConnect;
  1506. +    func_t    PutClientInServer;
  1507. +    func_t    ClientDisconnect;
  1508. +    func_t    SetNewParms;
  1509. +    func_t    SetChangeParms;
  1510. +} globalvars_t;
  1511. +
  1512. +typedef struct
  1513. +{
  1514. +    float    modelindex;
  1515. +    vec3_t    absmin;
  1516. +    vec3_t    absmax;
  1517. +    float    ltime;
  1518. +    float    movetype;
  1519. +    float    solid;
  1520. +    vec3_t    origin;
  1521. +    vec3_t    oldorigin;
  1522. +    vec3_t    velocity;
  1523. +    vec3_t    angles;
  1524. +    vec3_t    avelocity;
  1525. +    vec3_t    punchangle;
  1526. +    string_t    classname;
  1527. +    string_t    model;
  1528. +    float    frame;
  1529. +    float    skin;
  1530. +    float    effects;
  1531. +    vec3_t    mins;
  1532. +    vec3_t    maxs;
  1533. +    vec3_t    size;
  1534. +    func_t    touch;
  1535. +    func_t    use;
  1536. +    func_t    think;
  1537. +    func_t    blocked;
  1538. +    float    nextthink;
  1539. +    int    groundentity;
  1540. +    float    health;
  1541. +    float    frags;
  1542. +    float    weapon;
  1543. +    string_t    weaponmodel;
  1544. +    float    weaponframe;
  1545. +    float    currentammo;
  1546. +    float    ammo_shells;
  1547. +    float    ammo_nails;
  1548. +    float    ammo_rockets;
  1549. +    float    ammo_cells;
  1550. +    float    items;
  1551. +    float    takedamage;
  1552. +    int    chain;
  1553. +    float    deadflag;
  1554. +    vec3_t    view_ofs;
  1555. +    float    button0;
  1556. +    float    button1;
  1557. +    float    button2;
  1558. +    float    impulse;
  1559. +    float    fixangle;
  1560. +    vec3_t    v_angle;
  1561. +    float    idealpitch;
  1562. +    string_t    netname;
  1563. +    int    enemy;
  1564. +    float    flags;
  1565. +    float    colormap;
  1566. +    float    team;
  1567. +    float    max_health;
  1568. +    float    teleport_time;
  1569. +    float    armortype;
  1570. +    float    armorvalue;
  1571. +    float    waterlevel;
  1572. +    float    watertype;
  1573. +    float    ideal_yaw;
  1574. +    float    yaw_speed;
  1575. +    int    aiment;
  1576. +    int    goalentity;
  1577. +    float    spawnflags;
  1578. +    string_t    target;
  1579. +    string_t    targetname;
  1580. +    float    dmg_take;
  1581. +    float    dmg_save;
  1582. +    int    dmg_inflictor;
  1583. +    int    owner;
  1584. +    vec3_t    movedir;
  1585. +    string_t    message;
  1586. +    float    sounds;
  1587. +    string_t    noise;
  1588. +    string_t    noise1;
  1589. +    string_t    noise2;
  1590. +    string_t    noise3;
  1591. +} entvars_t;
  1592. +
  1593. +#define PROGHEADER_CRC 5927
  1594. diff -ur --new-file v106qc/progs.src kalq-src/progs.src
  1595. --- v106qc/progs.src    Thu Sep 26 11:15:40 1996
  1596. +++ kalq-src/progs.src    Thu Oct 24 22:45:30 1996
  1597. @@ -6,6 +6,7 @@
  1598.  ai.qc
  1599.  combat.qc
  1600.  items.qc
  1601. +wisp.qc         // Wisp code
  1602.  weapons.qc
  1603.  world.qc
  1604.  client.qc
  1605. @@ -33,3 +34,6 @@
  1606.  shalrath.qc        // registered
  1607.  enforcer.qc        // registered
  1608.  oldone.qc        // registered
  1609. +
  1610. +chain.qc        // Grappling Hook Code
  1611. +feign.qc                // Feign Death Code
  1612. diff -ur --new-file v106qc/triggers.qc kalq-src/triggers.qc
  1613. --- v106qc/triggers.qc    Thu Sep 26 11:15:40 1996
  1614. +++ kalq-src/triggers.qc    Thu Oct 24 23:16:30 1996
  1615. @@ -359,6 +359,10 @@
  1616.      force_retouch = 2;        // make sure even still objects get hit
  1617.  };
  1618.  
  1619. +/*
  1620. +//    REMmed out for the Teleport Weapons Patch by Kenneth Livingston
  1621. +//    aka KALWeb
  1622. +//    underhill@netpass.com
  1623.  void() teleport_touch =
  1624.  {
  1625.  local entity    t;
  1626. @@ -418,6 +422,55 @@
  1627.      }
  1628.      other.flags = other.flags - other.flags & FL_ONGROUND;
  1629.  };
  1630. +*/
  1631. +
  1632. +void() teleport_touch =
  1633. +{
  1634. +local entity    t;
  1635. +local vector    org;
  1636. +
  1637. +        if (self.targetname)
  1638. +        {
  1639. +                if (self.nextthink < time)
  1640. +                {
  1641. +                        return;         // not fired yet
  1642. +                }
  1643. +        }
  1644. +        
  1645. +// SLAY - Teleport weapons too!
  1646. +//      if (self.spawnflags & PLAYER_ONLY)
  1647. +//      {
  1648. +//              if (other.classname != "player")
  1649. +//                      return;
  1650. +//      }
  1651. +                        
  1652. +        SUB_UseTargets ();
  1653. +
  1654. +// put a tfog where the player was
  1655. +        spawn_tfog (other.origin);
  1656. +
  1657. +        t = find (world, targetname, self.target);
  1658. +        if (!t)
  1659. +                objerror ("couldn't find target");
  1660. +        
  1661. +// spawn a tfog flash in front of the destination
  1662. +        makevectors (t.mangle);
  1663. +        org = t.origin + 32 * v_forward;
  1664. +
  1665. +        spawn_tfog (org);
  1666. +        spawn_tdeath(t.origin, other);
  1667. +
  1668. +       
  1669. +        setorigin (other, t.origin);
  1670. +        other.angles = t.mangle;
  1671. +        other.fixangle = 1;             // turn this way immediately
  1672. +        other.teleport_time = time + 0.7;
  1673. +        if (other.flags & FL_ONGROUND)
  1674. +            other.flags = other.flags - FL_ONGROUND;
  1675. +        other.velocity = v_forward * 300;
  1676. +        other.flags = other.flags - other.flags & FL_ONGROUND;
  1677. +};
  1678. +
  1679.  
  1680.  /*QUAKED info_teleport_destination (.5 .5 .5) (-8 -8 -8) (8 8 32)
  1681.  This is the destination marker for a teleporter.  It should have a "targetname" field with the same value as a teleporter's "target" field.
  1682. diff -ur --new-file v106qc/weapons.qc kalq-src/weapons.qc
  1683. --- v106qc/weapons.qc    Mon Sep 30 03:08:08 1996
  1684. +++ kalq-src/weapons.qc    Fri Oct 25 06:00:58 1996
  1685. @@ -1,27 +1,80 @@
  1686.  /*
  1687. +    ADDED BY KTGOW:
  1688. +
  1689. +    Teleport Dropping:  Drop a teleport destination using impulse 41,
  1690. +      then teleport to that destination (from anywhere) using impulse 43.
  1691. +    Teleport Bombs: Fire off a Teleport Grenade using impulse 40, then
  1692. +      detonate it and teleport to its location using impulse 44.
  1693. +      Much of the code for telebombs was modified from the PIPEBOMB patch.
  1694. +      Many thanks to the author of that patch.  (AWESOME work!)
  1695. +
  1696. +    What about impulse 42?
  1697. +*/
  1698. +
  1699. +/*
  1700. +Bouncing Fragmentation Grenade!    7/28/96 by Steve Bond
  1701. +Email: wedge@nuc.net    WWW: http://www.nuc.net/quake
  1702. +
  1703. +>>>READ THE README!
  1704. +
  1705. +Hey ID! 
  1706. +If you are reading this, PUH-LEEZE fly me and John to Texas!
  1707. +We'll scrub the shitters at id for the chance to shake hands!
  1708. +(I mean - we'll wash our hands first and everything)
  1709. +
  1710.  */
  1711. +
  1712.  void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  1713.  void () player_run;
  1714.  void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  1715.  void(vector org, vector vel, float damage) SpawnBlood;
  1716.  void() SuperDamageSound;
  1717. +void() DropTeleport;
  1718. +void() Teleport_to_drop;
  1719. +void (vector org) spawn_tfog;
  1720. +void (vector org, entity death_owner) spawn_tdeath;
  1721. +void() W_FireTeleportBomb;
  1722. +void() TeleportBombTouch;
  1723. +void() Teleport_to_bomb;
  1724. +
  1725. +float bombtimer;
  1726. +
  1727. +void() W_FireBomb;
  1728. +void() BombTouch;
  1729. +void() BombExplode;
  1730. +void() BombExplosion;
  1731. +void() ShrapnelExplode;
  1732. +void() BombTime;
  1733. +void() W_FireGIBGUN;
  1734. +void() T_GIBTouch;
  1735. +void() GIBExplode;
  1736.  
  1737. +void() feign;   // experimental
  1738. +.float isfeign; // experimental
  1739.  
  1740.  // called by worldspawn
  1741.  void() W_Precache =
  1742.  {
  1743. -    precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  1744. -    precache_sound ("weapons/rocket1i.wav");    // spike gun
  1745. +    precache_sound ("weapons/r_exp3.wav");  // new rocket explosion
  1746. +    precache_sound ("weapons/rocket1i.wav");        // spike gun
  1747.      precache_sound ("weapons/sgun1.wav");
  1748. -    precache_sound ("weapons/guncock.wav");    // player shotgun
  1749. -    precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  1750. -    precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  1751. -    precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  1752. -    precache_sound ("weapons/spike2.wav");    // super spikes
  1753. -    precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  1754. -    precache_sound ("weapons/grenade.wav");    // grenade launcher
  1755. -    precache_sound ("weapons/bounce.wav");        // grenade bounce
  1756. -    precache_sound ("weapons/shotgn2.wav");    // super shotgun
  1757. +    precache_sound ("weapons/guncock.wav"); // player shotgun
  1758. +    precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  1759. +    precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  1760. +    precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  1761. +    precache_sound ("weapons/spike2.wav");  // super spikes
  1762. +    precache_sound ("weapons/tink1.wav");   // spikes tink (used in c code)
  1763. +    precache_sound ("weapons/grenade.wav"); // grenade launcher
  1764. +    precache_sound ("weapons/bounce.wav");          // grenade bounce
  1765. +    precache_sound ("weapons/shotgn2.wav"); // super shotgun
  1766. +    precache_sound ("items/damage2.wav");
  1767. +    precache_sound ("player/tornoff2.wav");
  1768. +    precache_sound ("player/lburn1.wav");
  1769. +        precache_sound2 ("blob/land1.wav");     // chain go splorch!
  1770. +        precache_sound ("plats/medplat1.wav");  // chain cranking out
  1771. +        precache_sound ("doors/ddoor1.wav");    // chain cranking in
  1772. +    precache_sound ("items/protect3.wav");
  1773. +    precache_sound ("items/damage3.wav");
  1774.  };
  1775.  
  1776.  float() crandom =
  1777. @@ -36,10 +89,9 @@
  1778.  */
  1779.  void() W_FireAxe =
  1780.  {
  1781. -    local    vector    source;
  1782. -    local    vector    org;
  1783. +    local   vector  source;
  1784. +    local   vector  org;
  1785.  
  1786. -    makevectors (self.v_angle);
  1787.      source = self.origin + '0 0 16';
  1788.      traceline (source, source + v_forward*64, FALSE, self);
  1789.      if (trace_fraction == 1.0)
  1790. @@ -54,7 +106,7 @@
  1791.          T_Damage (trace_ent, self, self, 20);
  1792.      }
  1793.      else
  1794. -    {    // hit wall
  1795. +    {       // hit wall
  1796.          sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  1797.          WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1798.          WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  1799. @@ -70,7 +122,7 @@
  1800.  
  1801.  vector() wall_velocity =
  1802.  {
  1803. -    local vector    vel;
  1804. +    local vector    vel;
  1805.      
  1806.      vel = normalize (self.velocity);
  1807.      vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  1808. @@ -88,8 +140,8 @@
  1809.  */
  1810.  void(vector org, vector vel) SpawnMeatSpray =
  1811.  {
  1812. -    local    entity missile, mpuff;
  1813. -    local    vector    org;
  1814. +    local   entity missile, mpuff;
  1815. +    local   vector  org;
  1816.  
  1817.      missile = spawn ();
  1818.      missile.owner = self;
  1819. @@ -108,7 +160,7 @@
  1820.      missile.think = SUB_Remove;
  1821.  
  1822.      setmodel (missile, "progs/zom_gib.mdl");
  1823. -    setsize (missile, '0 0 0', '0 0 0');        
  1824. +    setsize (missile, '0 0 0', '0 0 0');            
  1825.      setorigin (missile, org);
  1826.  };
  1827.  
  1828. @@ -129,7 +181,7 @@
  1829.  */
  1830.  void(float damage) spawn_touchblood =
  1831.  {
  1832. -    local vector    vel;
  1833. +    local vector    vel;
  1834.  
  1835.      vel = wall_velocity () * 0.2;
  1836.      SpawnBlood (self.origin + vel*0.01, vel, damage);
  1837. @@ -156,8 +208,8 @@
  1838.  ==============================================================================
  1839.  */
  1840.  
  1841. -entity    multi_ent;
  1842. -float    multi_damage;
  1843. +entity  multi_ent;
  1844. +float   multi_damage;
  1845.  
  1846.  void() ClearMultiDamage =
  1847.  {
  1848. @@ -202,7 +254,7 @@
  1849.  */
  1850.  void(float damage, vector dir) TraceAttack =
  1851.  {
  1852. -    local    vector    vel, org;
  1853. +    local   vector  vel, org;
  1854.      
  1855.      vel = normalize(dir + v_up*crandom() + v_right*crandom());
  1856.      vel = vel + 2*trace_plane_normal;
  1857. @@ -235,8 +287,8 @@
  1858.  */
  1859.  void(float shotcount, vector dir, vector spread) FireBullets =
  1860.  {
  1861. -    local    vector direction;
  1862. -    local    vector    src;
  1863. +    local   vector direction;
  1864. +    local   vector  src;
  1865.      
  1866.      makevectors(self.v_angle);
  1867.  
  1868. @@ -266,11 +318,11 @@
  1869.  {
  1870.      local vector dir;
  1871.  
  1872. -    sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);    
  1873. +    sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); 
  1874.  
  1875.      self.punchangle_x = -2;
  1876. -    
  1877. -    self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  1878. +
  1879. +        self.currentammo = self.ammo_shells;
  1880.      dir = aim (self, 100000);
  1881.      FireBullets (6, dir, '0.04 0.04 0');
  1882.  };
  1883. @@ -291,7 +343,7 @@
  1884.          return;
  1885.      }
  1886.          
  1887. -    sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);    
  1888. +    sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); 
  1889.  
  1890.      self.punchangle_x = -4;
  1891.      
  1892. @@ -309,12 +361,12 @@
  1893.  ==============================================================================
  1894.  */
  1895.  
  1896. -void()    s_explode1    =    [0,        s_explode2] {};
  1897. -void()    s_explode2    =    [1,        s_explode3] {};
  1898. -void()    s_explode3    =    [2,        s_explode4] {};
  1899. -void()    s_explode4    =    [3,        s_explode5] {};
  1900. -void()    s_explode5    =    [4,        s_explode6] {};
  1901. -void()    s_explode6    =    [5,        SUB_Remove] {};
  1902. +void()  s_explode1      =       [0,             s_explode2] {};
  1903. +void()  s_explode2      =       [1,             s_explode3] {};
  1904. +void()  s_explode3      =       [2,             s_explode4] {};
  1905. +void()  s_explode4      =       [3,             s_explode5] {};
  1906. +void()  s_explode5      =       [4,             s_explode6] {};
  1907. +void()  s_explode6      =       [5,             SUB_Remove] {};
  1908.  
  1909.  void() BecomeExplosion =
  1910.  {
  1911. @@ -328,10 +380,10 @@
  1912.  
  1913.  void() T_MissileTouch =
  1914.  {
  1915. -    local float    damg;
  1916. +    local float     damg;
  1917.  
  1918.      if (other == self.owner)
  1919. -        return;        // don't explode on owner
  1920. +        return;         // don't explode on owner
  1921.  
  1922.      if (pointcontents(self.origin) == CONTENT_SKY)
  1923.      {
  1924. @@ -344,7 +396,7 @@
  1925.      if (other.health)
  1926.      {
  1927.          if (other.classname == "monster_shambler")
  1928. -            damg = damg * 0.5;    // mostly immune
  1929. +            damg = damg * 0.5;      // mostly immune
  1930.          T_Damage (other, self, self.owner, damg );
  1931.      }
  1932.  
  1933. @@ -352,7 +404,7 @@
  1934.      // was done in the impact
  1935.      T_RadiusDamage (self, self.owner, 120, other);
  1936.  
  1937. -//    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  1938. +//      sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  1939.      self.origin = self.origin - 8*normalize(self.velocity);
  1940.  
  1941.      WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  1942. @@ -373,7 +425,7 @@
  1943.  */
  1944.  void() W_FireRocket =
  1945.  {
  1946. -    local    entity missile, mpuff;
  1947. +    local   entity missile, mpuff;
  1948.      
  1949.      self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  1950.      
  1951. @@ -385,9 +437,8 @@
  1952.      missile.owner = self;
  1953.      missile.movetype = MOVETYPE_FLYMISSILE;
  1954.      missile.solid = SOLID_BBOX;
  1955. -    missile.classname = "missile";
  1956.          
  1957. -// set missile speed    
  1958. +// set missile speed    
  1959.  
  1960.      makevectors (self.v_angle);
  1961.      missile.velocity = aim(self, 1000);
  1962. @@ -401,7 +452,7 @@
  1963.      missile.think = SUB_Remove;
  1964.  
  1965.      setmodel (missile, "progs/missile.mdl");
  1966. -    setsize (missile, '0 0 0', '0 0 0');        
  1967. +    setsize (missile, '0 0 0', '0 0 0');            
  1968.      setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  1969.  };
  1970.  
  1971. @@ -418,11 +469,102 @@
  1972.  LightningDamage
  1973.  =================
  1974.  */
  1975. +void() ChangeLightningMode =
  1976. +{
  1977. +        sprint(self,"Changing thunderbolt mode to ");
  1978. +        if (self.items & IT_TRACTOR_BEAM)
  1979. +        {
  1980. +                self.items = self.items - (self.items & IT_TRACTOR_BEAM);
  1981. +                sprint(self,"lightning.\n");
  1982. +        }
  1983. +        else
  1984. +        {
  1985. +                self.items = self.items | IT_TRACTOR_BEAM;
  1986. +                sprint(self,"tractor beam.\n");
  1987. +        }
  1988. +};
  1989. +
  1990. +void(vector p1, vector p2, entity from, float damage) TractorEffect =
  1991. +{
  1992. +    local entity        e1, e2;
  1993. +    local vector        f;
  1994. +
  1995. +    f = p2 - p1;
  1996. +    normalize (f);
  1997. +    f_x = 0 - f_y;
  1998. +    f_y = f_x;
  1999. +    f_z = 0;
  2000. +    f = f*16;
  2001. +
  2002. +    e1 = e2 = world;
  2003. +
  2004. +    traceline (p1, p2, FALSE, self);
  2005. +    e1 = trace_ent;
  2006. +        if (trace_ent.takedamage && trace_ent.classname != "trigger_multiple" && trace_ent.classname != "door")
  2007. +        {
  2008. +                trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
  2009. +                trace_ent.movetype = MOVETYPE_TOSS;
  2010. +                trace_ent.nextthink = time + 0.5;
  2011. +    }
  2012. +
  2013. +    traceline (p1 + f, p2 + f, FALSE, self);
  2014. +        if (trace_ent != e1 && trace_ent.takedamage && trace_ent.classname != "trigger_multiple" && trace_ent.classname != "door")
  2015. +    {
  2016. +                trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
  2017. +                trace_ent.movetype = MOVETYPE_TOSS;
  2018. +                trace_ent.nextthink = time + 0.5;
  2019. +    }
  2020. +    e2 = trace_ent;
  2021. +
  2022. +    traceline (p1 - f, p2 - f, FALSE, self);
  2023. +        if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage && trace_ent.classname != "trigger_multiple" && trace_ent.classname != "door")
  2024. +    {
  2025. +                trace_ent.origin = self.origin+v_forward*vlen(self.origin-trace_ent.origin);
  2026. +                trace_ent.movetype = MOVETYPE_TOSS;
  2027. +                trace_ent.nextthink = time + 0.5;
  2028. +    }
  2029. +};
  2030. +void() W_UseTractor =
  2031. +{
  2032. +    local    vector        org;
  2033. +
  2034. +//      sprint(self,"W_UseTractor running\n");
  2035. +    if (self.ammo_cells < 1)
  2036. +    {
  2037. +        return;
  2038. +    }
  2039. +
  2040. +    if (self.t_width < time)
  2041. +    {
  2042. +        sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  2043. +        self.t_width = time + 0.6;
  2044. +    }
  2045. +    self.punchangle_x = -2;
  2046. +
  2047. +//      self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  2048. +
  2049. +    org = self.origin + '0 0 16';
  2050. +
  2051. +    traceline (org, org + v_forward*600, TRUE, self);
  2052. +
  2053. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  2054. +    WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  2055. +    WriteEntity (MSG_BROADCAST, self);
  2056. +    WriteCoord (MSG_BROADCAST, org_x);
  2057. +    WriteCoord (MSG_BROADCAST, org_y);
  2058. +    WriteCoord (MSG_BROADCAST, org_z);
  2059. +    WriteCoord (MSG_BROADCAST, trace_endpos_x);
  2060. +    WriteCoord (MSG_BROADCAST, trace_endpos_y);
  2061. +    WriteCoord (MSG_BROADCAST, trace_endpos_z);
  2062. +
  2063. +    TractorEffect (self.origin, trace_endpos + v_forward*4, self, 30);
  2064. +};
  2065. +
  2066.  void(vector p1, vector p2, entity from, float damage) LightningDamage =
  2067.  {
  2068.      local entity        e1, e2;
  2069.      local vector        f;
  2070. -    
  2071. +
  2072.      f = p2 - p1;
  2073.      normalize (f);
  2074.      f_x = 0 - f_y;
  2075. @@ -465,7 +607,12 @@
  2076.  void() W_FireLightning =
  2077.  {
  2078.      local    vector        org;
  2079. -    local    float        cells;
  2080. +
  2081. +        if (self.items & IT_TRACTOR_BEAM)
  2082. +        {
  2083. +                W_UseTractor();
  2084. +                return;
  2085. +        }
  2086.  
  2087.      if (self.ammo_cells < 1)
  2088.      {
  2089. @@ -477,10 +624,9 @@
  2090.  // explode if under water
  2091.      if (self.waterlevel > 1)
  2092.      {
  2093. -        cells = self.ammo_cells;
  2094. +        T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  2095.          self.ammo_cells = 0;
  2096.          W_SetCurrentAmmo ();
  2097. -        T_RadiusDamage (self, self, 35*cells, world);
  2098.          return;
  2099.      }
  2100.  
  2101. @@ -494,7 +640,7 @@
  2102.      self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  2103.  
  2104.      org = self.origin + '0 0 16';
  2105. -    
  2106. +
  2107.      traceline (org, org + v_forward*600, TRUE, self);
  2108.  
  2109.      WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  2110. @@ -530,13 +676,13 @@
  2111.  void() GrenadeTouch =
  2112.  {
  2113.      if (other == self.owner)
  2114. -        return;        // don't explode on owner
  2115. +        return;         // don't explode on owner
  2116.      if (other.takedamage == DAMAGE_AIM)
  2117.      {
  2118.          GrenadeExplode();
  2119.          return;
  2120.      }
  2121. -    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  2122. +    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  2123.      if (self.velocity == '0 0 0')
  2124.          self.avelocity = '0 0 0';
  2125.  };
  2126. @@ -548,7 +694,7 @@
  2127.  */
  2128.  void() W_FireGrenade =
  2129.  {
  2130. -    local    entity missile, mpuff;
  2131. +    local   entity missile, mpuff;
  2132.      
  2133.      self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  2134.      
  2135. @@ -562,7 +708,7 @@
  2136.      missile.solid = SOLID_BBOX;
  2137.      missile.classname = "grenade";
  2138.          
  2139. -// set missile speed    
  2140. +// set missile speed    
  2141.  
  2142.      makevectors (self.v_angle);
  2143.  
  2144. @@ -586,7 +732,7 @@
  2145.      missile.think = GrenadeExplode;
  2146.  
  2147.      setmodel (missile, "progs/grenade.mdl");
  2148. -    setsize (missile, '0 0 0', '0 0 0');        
  2149. +    setsize (missile, '0 0 0', '0 0 0');            
  2150.      setorigin (missile, self.origin);
  2151.  };
  2152.  
  2153. @@ -616,9 +762,10 @@
  2154.      newmis.touch = spike_touch;
  2155.      newmis.classname = "spike";
  2156.      newmis.think = SUB_Remove;
  2157. -    newmis.nextthink = time + 6;
  2158. +// Bump the nail's lifespan up to 11 seconds(?),so it will stick for a bit        
  2159. +    newmis.nextthink = time + 11;
  2160.      setmodel (newmis, "progs/spike.mdl");
  2161. -    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  2162. +    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  2163.      setorigin (newmis, org);
  2164.  
  2165.      newmis.velocity = dir * 1000;
  2166. @@ -626,8 +773,8 @@
  2167.  
  2168.  void() W_FireSuperSpikes =
  2169.  {
  2170. -    local vector    dir;
  2171. -    local entity    old;
  2172. +    local vector    dir;
  2173. +    local entity    old;
  2174.      
  2175.      sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  2176.      self.attack_finished = time + 0.2;
  2177. @@ -636,14 +783,14 @@
  2178.      launch_spike (self.origin + '0 0 16', dir);
  2179.      newmis.touch = superspike_touch;
  2180.      setmodel (newmis, "progs/s_spike.mdl");
  2181. -    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  2182. +    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);               
  2183.      self.punchangle_x = -2;
  2184.  };
  2185.  
  2186.  void(float ox) W_FireSpikes =
  2187.  {
  2188. -    local vector    dir;
  2189. -    local entity    old;
  2190. +    local vector    dir;
  2191. +    local entity    old;
  2192.      
  2193.      makevectors (self.v_angle);
  2194.      
  2195. @@ -679,7 +826,7 @@
  2196.          return;
  2197.  
  2198.      if (other.solid == SOLID_TRIGGER)
  2199. -        return;    // trigger field, do nothing
  2200. +        return; // trigger field, do nothing
  2201.  
  2202.      if (pointcontents(self.origin) == CONTENT_SKY)
  2203.      {
  2204. @@ -692,6 +839,7 @@
  2205.      {
  2206.          spawn_touchblood (9);
  2207.          T_Damage (other, self, self.owner, 9);
  2208. +        remove(self);
  2209.      }
  2210.      else
  2211.      {
  2212. @@ -708,6 +856,12 @@
  2213.          WriteCoord (MSG_BROADCAST, self.origin_z);
  2214.      }
  2215.  
  2216. +/*
  2217. +DO NOT let the nail remove itself. This section of code is only executed
  2218. +when the nail has hit a wall, floor, or plat. These are places we want the 
  2219. +nail to stick, so we comment out the REMOVE(SELF); function call
  2220. +*/
  2221. +    self.velocity='0 0 0'; // make the nail stop!
  2222.      remove(self);
  2223.  
  2224.  };
  2225. @@ -719,7 +873,7 @@
  2226.          return;
  2227.  
  2228.      if (other.solid == SOLID_TRIGGER)
  2229. -        return;    // trigger field, do nothing
  2230. +        return; // trigger field, do nothing
  2231.  
  2232.      if (pointcontents(self.origin) == CONTENT_SKY)
  2233.      {
  2234. @@ -747,8 +901,270 @@
  2235.  };
  2236.  
  2237.  
  2238. +
  2239. +
  2240. +
  2241. +
  2242. +/*========================================================================
  2243. +BOUNCING FRAGMENTATION GRENADE - Version .9
  2244. +7/28/96 - Steve Bond  email:wedge@nuc.net
  2245. +http://www.nuc.net/quake
  2246. +=======================================================================*/
  2247. +
  2248. +//This code segment handles the impact of shrapnel
  2249. +//this is merely id's superspike_touch code, reworked
  2250. +void() shrapnel_touch =
  2251. +{
  2252. +local float rand;
  2253. +// has the shrapnel hit a switch? 
  2254. +    if (other.solid == SOLID_TRIGGER)
  2255. +        return; // trigger field, do nothing
  2256. +
  2257. +// has the shrapnel hit the sky?
  2258. +    if (pointcontents(self.origin) == CONTENT_SKY)
  2259. +    {
  2260. +        remove(self);
  2261. +        return;
  2262. +    }
  2263. +    
  2264. +// has the shrapnel hit a living thing?
  2265. +    if (other.takedamage)
  2266. +    {
  2267. +        spawn_touchblood (18);
  2268. +        T_Damage (other, self, self.owner, 18);
  2269. +    }
  2270. +    else
  2271. +    {
  2272. +        WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  2273. +        WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  2274. +        WriteCoord (MSG_BROADCAST, self.origin_x);
  2275. +        WriteCoord (MSG_BROADCAST, self.origin_y);
  2276. +        WriteCoord (MSG_BROADCAST, self.origin_z);
  2277. +    }
  2278. +
  2279. +};
  2280. +
  2281. +/*
  2282. +Code to spawn ONE randomly directed piece of shrapnel
  2283. +this is id's launch_spike code, reworked
  2284. +Pass a vector to this function to determine the shrap's origin
  2285. +*/
  2286. +void (vector org, float spin, entity shooter) launch_shrapnel=
  2287. +{
  2288. +    local float xdir,ydir,zdir;
  2289. +    
  2290. +//Assign a random direction for the shrapnel to fly in
  2291. +    xdir = 110 * random() - 55;
  2292. +    ydir = 110 * random() - 55;
  2293. +    zdir = 50 * random() - 25;
  2294. +
  2295. +    newmis = spawn ();
  2296. +    newmis.owner = shooter;
  2297. +    newmis.movetype = MOVETYPE_BOUNCE;
  2298. +    self.touch = SUB_Null;
  2299. +    newmis.solid = SOLID_BBOX;
  2300. +
  2301. +    newmis.touch = shrapnel_touch;
  2302. +    newmis.classname = "spike";
  2303. +    newmis.think =     ShrapnelExplode;
  2304. +    
  2305. +// this is how many seconds(?) the nails can exist.        
  2306. +    newmis.nextthink = time + 1;
  2307. +    
  2308. +// speed at which to move the shrapnel        
  2309. +    newmis.velocity_x = xdir * 2;
  2310. +    newmis.velocity_y = ydir * 2;
  2311. +    newmis.velocity_z = zdir * 15;
  2312. +
  2313. +/*
  2314. +as best I can figure, AVELOCITY means "attitude velocity"        
  2315. +or something thereabouts. Anyway, it makes shit spin on 
  2316. +the x,y,z axes by the given velocity for each axis. In this 
  2317. +case, it makes the shrapnel spin in flight. Good stuff.
  2318. +this segment assigns one of five preset attitudes for 
  2319. +each piece of shrapnel, based on the number passed to the
  2320. +function.
  2321. +*/        
  2322. +    if (spin == 0)
  2323. +    newmis.avelocity='250 300 400';
  2324. +    if (spin == 1)
  2325. +    newmis.avelocity='400 250 300';
  2326. +    if (spin == 2)
  2327. +    newmis.avelocity='300 400 250';
  2328. +    if (spin == 3)
  2329. +    newmis.avelocity='300 300 300';
  2330. +    if (spin == 4) 
  2331. +    newmis.avelocity='400 250 400';
  2332. +
  2333. +    setmodel (newmis, "progs/grenade.mdl");
  2334. +    setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  2335. +    setorigin (newmis, org);
  2336. +};
  2337. +
  2338. +// This code segment detonates the 'second stage' of the grenade
  2339. +// (After it has popped up)
  2340. +void()  BouncerExplode =
  2341. +{
  2342. +    
  2343. +// Do the damage
  2344. +    T_RadiusDamage (self, self.owner, 120, world);
  2345. +// Tell the network
  2346. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  2347. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  2348. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  2349. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  2350. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  2351. +
  2352. +// Let Quake handle the explosion and deallocation of the grenade        
  2353. +    self.solid=SOLID_NOT;
  2354. +    BecomeExplosion ();
  2355. +
  2356. +// Launch a hail (20 pieces) of shrapnel
  2357. +    launch_shrapnel (self.origin + '0 0 -1',0,self.owner);
  2358. +    launch_shrapnel (self.origin + '0 0 -1',1,self.owner);
  2359. +    launch_shrapnel (self.origin + '0 0 -1',2,self.owner);
  2360. +    launch_shrapnel (self.origin + '0 0 -1',3,self.owner);
  2361. +    launch_shrapnel (self.origin + '0 0 -1',4,self.owner);
  2362. +    launch_shrapnel (self.origin + '0 0 -1',0,self.owner);
  2363. +    launch_shrapnel (self.origin + '0 0 -1',1,self.owner);
  2364. +    launch_shrapnel (self.origin + '0 0 -1',2,self.owner);
  2365. +    launch_shrapnel (self.origin + '0 0 -1',3,self.owner);
  2366. +    launch_shrapnel (self.origin + '0 0 -1',4,self.owner);
  2367. +    
  2368. +};
  2369. +
  2370. +/*
  2371. +This code segment makes the 'first stage' of the bouncer pop upward
  2372. +after it's time has expired.
  2373. +*/
  2374. +void() BouncerTouch;
  2375. +void() BouncerPopUp=
  2376. +{
  2377. +    local entity missile, mpuff;
  2378. +
  2379. +// Make the grenade stop
  2380. +    self.movetype=MOVETYPE_NONE;
  2381. +    self.velocity='0 0 0';
  2382. +// Draw a tiny explosion (no particles)        
  2383. +    setmodel (self, "progs/s_explod.spr");
  2384. +    s_explode1 ();
  2385. +// Make the :FOOMP: grenade launcher sound        
  2386. +    sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  2387. +// Spawn and animate the 'second stage'
  2388. +    missile = spawn ();
  2389. +    missile.owner = self.owner;
  2390. +    missile.movetype = MOVETYPE_BOUNCE;
  2391. +    missile.solid = SOLID_BBOX;
  2392. +    missile.classname = "grenade";
  2393. +// Set speed
  2394. +    missile.velocity = '0 0 650';
  2395. +    missile.angles = vectoangles(missile.velocity);
  2396. +    missile.touch = BouncerTouch;
  2397. +// Set Duration
  2398. +    missile.nextthink = time + 1;
  2399. +    missile.think = BouncerExplode;
  2400. +
  2401. +    setmodel (missile, "progs/missile.mdl");
  2402. +    setsize (missile, '0 0 0', '0 0 0');
  2403. +    setorigin (missile, self.origin);
  2404. +};
  2405. +
  2406. +// This code segment handles collisions for the 'first stage'
  2407. +// Of the grenade (after launch and before popup)
  2408. +
  2409. +void() BouncerTouch =
  2410. +{
  2411. +//Did the grenade hit a 'living' thing?
  2412. +    if (other.takedamage)
  2413. +    {
  2414. +// yes, so play the bounce sound
  2415. +    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
  2416. +// now, exit the function without cause damage to the thing        
  2417. +    return;
  2418. +    }
  2419. +
  2420. +// This controls what happens when the grenade hits walls, etz        
  2421. +// It just plays the sound and bounces on
  2422. +    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
  2423. +    if (self.velocity == '0 0 0')
  2424. +        self.avelocity = '0 0 0';
  2425. +};
  2426. +
  2427. +/*
  2428. +This code segment handles the launching of the Bouncing Fragmentation Grenade
  2429. +this is a reworked copy of id's W_launchgrenade code
  2430. +*/
  2431. +void() W_LaunchBouncer =
  2432. +{
  2433. +// If player doesn't have 3 or more rockets, don't launch
  2434. +    if ((self.ammo_rockets < 10) || (self.weapon != IT_FIREWALL))
  2435. +    {
  2436. +    return;
  2437. +    }
  2438. +
  2439. +    local   entity missile, mpuff;
  2440. +    
  2441. +// Take 3 rockets from the player        
  2442. +    self.currentammo = self.ammo_rockets = self.ammo_rockets - 10;
  2443. +    
  2444. +    //sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  2445. +/*
  2446. +self.punchangle_x (x, y, or z) defines how hard the weapon         
  2447. +recoils (or 'punches' the player, making the screen shake)
  2448. +*/        
  2449. +    self.punchangle_x = -2;
  2450. +
  2451. +// This spawns the grenade - it is all id's standard grenade code        
  2452. +    missile = spawn ();
  2453. +    missile.owner = self;
  2454. +    missile.movetype = MOVETYPE_BOUNCE;
  2455. +    missile.solid = SOLID_BBOX;
  2456. +    missile.classname = "grenade";
  2457. +        
  2458. +// set missile speed    
  2459. +
  2460. +    makevectors (self.v_angle);
  2461. +
  2462. +    if (self.v_angle_x)
  2463. +        missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  2464. +    else
  2465. +    {
  2466. +        missile.velocity = aim(self, 10000);
  2467. +        missile.velocity = missile.velocity * 600;
  2468. +        missile.velocity_z = 200;
  2469. +    }
  2470. +
  2471. +    missile.avelocity = '300 300 300';
  2472. +
  2473. +    missile.angles = vectoangles(missile.velocity);
  2474. +    
  2475. +// if the grenade touches anything, BouncerTouch() is called        
  2476. +    missile.touch = BouncerTouch;
  2477. +    
  2478. +// Grenade has a maximum lifespan of 1.5 (seconds?)
  2479. +// set missile duration
  2480. +    missile.nextthink = time + 1;
  2481. +    
  2482. +// when the grenade's lifespan has expired, BouncerPopUp() is called        
  2483. +    missile.think = BouncerPopUp;
  2484. +
  2485. +    setmodel (missile, "progs/grenade.mdl");
  2486. +    setsize (missile, '0 0 0', '0 0 0');            
  2487. +    setorigin (missile, self.origin);
  2488. +//    sprint(self,"Gib 'em!\n");
  2489. +};
  2490.  /*
  2491.  ===============================================================================
  2492. +End of Bouncing Fragmentation Grenade code.
  2493. +===============================================================================
  2494. +*/
  2495. +
  2496. +
  2497. +
  2498. +
  2499. +
  2500. +
  2501. +/*
  2502.  
  2503.  PLAYER WEAPON USE
  2504.  
  2505. @@ -757,7 +1173,7 @@
  2506.  
  2507.  void() W_SetCurrentAmmo =
  2508.  {
  2509. -    player_run ();        // get out of any weapon firing states
  2510. +    player_run ();          // get out of any weapon firing states
  2511.  
  2512.      self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  2513.      
  2514. @@ -767,9 +1183,18 @@
  2515.          self.weaponmodel = "progs/v_axe.mdl";
  2516.          self.weaponframe = 0;
  2517.      }
  2518. -    else if (self.weapon == IT_SHOTGUN)
  2519. +//===============================================
  2520. +        else if (self.weapon == IT_HOOK)
  2521. +        {
  2522. +                self.currentammo = 0;
  2523. +                self.weaponmodel = "progs/v_axe.mdl";
  2524. +                self.weaponframe = 0;
  2525. +        }
  2526. +//===============================================
  2527. +
  2528. +        else if (self.weapon == IT_SHOTGUN)
  2529.      {
  2530. -        self.currentammo = self.ammo_shells;
  2531. +                self.currentammo = self.ammo_shells;
  2532.          self.weaponmodel = "progs/v_shot.mdl";
  2533.          self.weaponframe = 0;
  2534.          self.items = self.items | IT_SHELLS;
  2535. @@ -795,14 +1220,14 @@
  2536.          self.weaponframe = 0;
  2537.          self.items = self.items | IT_NAILS;
  2538.      }
  2539. -    else if (self.weapon == IT_GRENADE_LAUNCHER)
  2540. +    else if ((self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_FIREWALL) || (self.weapon == IT_BOMB))
  2541.      {
  2542.          self.currentammo = self.ammo_rockets;
  2543.          self.weaponmodel = "progs/v_rock.mdl";
  2544.          self.weaponframe = 0;
  2545.          self.items = self.items | IT_ROCKETS;
  2546.      }
  2547. -    else if (self.weapon == IT_ROCKET_LAUNCHER)
  2548. +    else if (self.weapon == IT_ROCKET_LAUNCHER || (self.weapon == IT_GIBGUN))
  2549.      {
  2550.          self.currentammo = self.ammo_rockets;
  2551.          self.weaponmodel = "progs/v_rock2.mdl";
  2552. @@ -826,20 +1251,29 @@
  2553.  
  2554.  float() W_BestWeapon =
  2555.  {
  2556. -    local    float    it;
  2557. +    local   float   it;
  2558.      
  2559.      it = self.items;
  2560.  
  2561. -    if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  2562. -            return IT_LIGHTNING;
  2563. -    if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  2564. +    if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  2565. +        return IT_LIGHTNING;
  2566. +    else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  2567.          return IT_SUPER_NAILGUN;
  2568. -    if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  2569. +    else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  2570.          return IT_SUPER_SHOTGUN;
  2571. -    if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  2572. +    else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  2573.          return IT_NAILGUN;
  2574. -    if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  2575. +    else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  2576.          return IT_SHOTGUN;
  2577. +        
  2578. +/*
  2579. +    if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  2580. +        return IT_ROCKET_LAUNCHER;
  2581. +    else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  2582. +        return IT_GRENADE_LAUNCHER;
  2583. +
  2584. +*/
  2585. +
  2586.      return IT_AXE;
  2587.  };
  2588.  
  2589. @@ -848,7 +1282,7 @@
  2590.      if (self.currentammo > 0)
  2591.          return TRUE;
  2592.  
  2593. -    if (self.weapon == IT_AXE)
  2594. +        if (self.weapon == IT_AXE || self.weapon == IT_HOOK)
  2595.          return TRUE;
  2596.      
  2597.      self.weapon = W_BestWeapon ();
  2598. @@ -866,24 +1300,26 @@
  2599.  An attack impulse can be triggered now
  2600.  ============
  2601.  */
  2602. -void()    player_axe1;
  2603. -void()    player_axeb1;
  2604. -void()    player_axec1;
  2605. -void()    player_axed1;
  2606. -void()    player_shot1;
  2607. -void()    player_nail1;
  2608. -void()    player_light1;
  2609. -void()    player_rocket1;
  2610. +void()  player_axe1;
  2611. +void()  player_axeb1;
  2612. +void()  player_axec1;
  2613. +void()  player_axed1;
  2614. +void()  player_shot1;
  2615. +void()  player_nail1;
  2616. +void()  player_light1;
  2617. +void()  player_rocket1;
  2618. +void()    player_chain1;
  2619. +void()  player_chain3;
  2620.  
  2621.  void() W_Attack =
  2622.  {
  2623. -    local    float    r;
  2624. +    local   float   r;
  2625.  
  2626.      if (!W_CheckNoAmmo ())
  2627.          return;
  2628.  
  2629. -    makevectors    (self.v_angle);            // calculate forward angle for velocity
  2630. -    self.show_hostile = time + 1;    // wake monsters up
  2631. +    makevectors     (self.v_angle);                 // calculate forward angle for velocity
  2632. +    self.show_hostile = time + 1;   // wake monsters up
  2633.  
  2634.      if (self.weapon == IT_AXE)
  2635.      {
  2636. @@ -937,6 +1373,31 @@
  2637.          self.attack_finished = time + 0.1;
  2638.          sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  2639.      }
  2640. +    else if (self.weapon == IT_FIREWALL)
  2641. +    {
  2642. +        W_LaunchBouncer();
  2643. +        self.attack_finished = time + 0.8;
  2644. +    }
  2645. +    else if (self.weapon == IT_BOMB)
  2646. +    {
  2647. +        W_FireBomb();
  2648. +        self.attack_finished = time + 0.8;
  2649. +    }    
  2650. +    else if (self.weapon == IT_GIBGUN)
  2651. +    {
  2652. +        W_FireGIBGUN();
  2653. +        self.attack_finished = time + 0.4;
  2654. +    }    
  2655. +
  2656. +//===============================================
  2657. +        else if (self.weapon == IT_HOOK)
  2658. +        {
  2659. +                if (!self.hook_out) {player_chain1();}
  2660. +                else {player_chain3();}
  2661. +                self.attack_finished = time + 0.1;
  2662. +        }
  2663. +//===============================================
  2664. +
  2665.  };
  2666.  
  2667.  /*
  2668. @@ -947,68 +1408,103 @@
  2669.  */
  2670.  void() W_ChangeWeapon =
  2671.  {
  2672. -    local    float    it, am, fl;
  2673. +    local   float   it, am, fl;
  2674.      
  2675.      it = self.items;
  2676.      am = 0;
  2677.      
  2678.      if (self.impulse == 1)
  2679.      {
  2680. -        fl = IT_AXE;
  2681. +//===============================================
  2682. +        if (self.weapon == IT_AXE) {
  2683. +                fl = IT_HOOK;
  2684. +                sprint (self, "Grappling Hook selected.\n"); }
  2685. +        else {
  2686. +                fl = IT_AXE;
  2687. +                sprint (self, "Axe selected.\n");
  2688. +             }
  2689. +//===============================================
  2690.      }
  2691.      else if (self.impulse == 2)
  2692.      {
  2693.          fl = IT_SHOTGUN;
  2694.          if (self.ammo_shells < 1)
  2695.              am = 1;
  2696. -    }
  2697. +                if (self.ammo_shells < 1) sprint (self, "Shotgun selected.\n");
  2698. +        }
  2699.      else if (self.impulse == 3)
  2700.      {
  2701.          fl = IT_SUPER_SHOTGUN;
  2702.          if (self.ammo_shells < 2)
  2703.              am = 1;
  2704. -    }        
  2705. +                if (self.ammo_shells < 2) sprint (self, "Super Shotgun selected.\n");
  2706. +        }
  2707.      else if (self.impulse == 4)
  2708.      {
  2709.          fl = IT_NAILGUN;
  2710.          if (self.ammo_nails < 1)
  2711.              am = 1;
  2712. +                if (!am) sprint (self, "Nailgun selected.\n");
  2713.      }
  2714.      else if (self.impulse == 5)
  2715.      {
  2716.          fl = IT_SUPER_NAILGUN;
  2717.          if (self.ammo_nails < 2)
  2718. -            am = 1;
  2719. -    }
  2720. +                        am = 1;
  2721. +                if (!am) sprint (self, "Super Nailgun selected.\n");
  2722. +        }
  2723.      else if (self.impulse == 6)
  2724.      {
  2725. +        if (self.weapon == IT_GRENADE_LAUNCHER)
  2726. +        { 
  2727. +            self.weapon = IT_FIREWALL;
  2728. +            centerprint(self,"Firewall mode\n");
  2729. +            return;
  2730. +        } 
  2731. +        if (self.weapon == IT_FIREWALL)
  2732. +        {
  2733. +            self.weapon = IT_BOMB;
  2734. +            centerprint(self,"Proximity mine mode\n");
  2735. +            return;
  2736. +        }  
  2737. +
  2738.          fl = IT_GRENADE_LAUNCHER;
  2739.          if (self.ammo_rockets < 1)
  2740.              am = 1;
  2741. +        if (!am) centerprint(self,"Grenade Launcher Mode\n");
  2742.      }
  2743.      else if (self.impulse == 7)
  2744.      {
  2745. +        if (self.weapon == IT_ROCKET_LAUNCHER)
  2746. +        { 
  2747. +            self.weapon = IT_GIBGUN;
  2748. +            centerprint(self,"Gibgun mode\n");
  2749. +            return;
  2750. +        } 
  2751. +        
  2752.          fl = IT_ROCKET_LAUNCHER;
  2753.          if (self.ammo_rockets < 1)
  2754.              am = 1;
  2755. +        if (!am) centerprint(self,"Rocket Launcher Mode\n");
  2756.      }
  2757.      else if (self.impulse == 8)
  2758.      {
  2759. -        fl = IT_LIGHTNING;
  2760. +                fl = IT_LIGHTNING;
  2761.          if (self.ammo_cells < 1)
  2762.              am = 1;
  2763. +                ChangeLightningMode();
  2764.      }
  2765.  
  2766.      self.impulse = 0;
  2767.      
  2768.      if (!(self.items & fl))
  2769. -    {    // don't have the weapon or the ammo
  2770. +    {       // don't have the weapon or the ammo
  2771.          sprint (self, "no weapon.\n");
  2772.          return;
  2773.      }
  2774.      
  2775.      if (am)
  2776. -    {    // don't have the ammo
  2777. +    {       // don't have the ammo
  2778.          sprint (self, "not enough ammo.\n");
  2779.          return;
  2780.      }
  2781. @@ -1016,7 +1512,7 @@
  2782.  //
  2783.  // set weapon, set ammo
  2784.  //
  2785. -    self.weapon = fl;        
  2786. +    self.weapon = fl;               
  2787.      W_SetCurrentAmmo ();
  2788.  };
  2789.  
  2790. @@ -1060,7 +1556,7 @@
  2791.  */
  2792.  void() CycleWeaponCommand =
  2793.  {
  2794. -    local    float    it, am;
  2795. +    local   float   it, am;
  2796.      
  2797.      it = self.items;
  2798.      self.impulse = 0;
  2799. @@ -1074,7 +1570,13 @@
  2800.              self.weapon = IT_AXE;
  2801.          }
  2802.          else if (self.weapon == IT_AXE)
  2803. -        {
  2804. +//===============================================
  2805. +                {
  2806. +                        self.weapon == IT_HOOK;
  2807. +                }
  2808. +                else if (self.weapon == IT_HOOK)
  2809. +//===============================================
  2810. +                {
  2811.              self.weapon = IT_SHOTGUN;
  2812.              if (self.ammo_shells < 1)
  2813.                  am = 1;
  2814. @@ -1084,7 +1586,7 @@
  2815.              self.weapon = IT_SUPER_SHOTGUN;
  2816.              if (self.ammo_shells < 2)
  2817.                  am = 1;
  2818. -        }        
  2819. +        }               
  2820.          else if (self.weapon == IT_SUPER_SHOTGUN)
  2821.          {
  2822.              self.weapon = IT_NAILGUN;
  2823. @@ -1103,20 +1605,20 @@
  2824.              if (self.ammo_rockets < 1)
  2825.                  am = 1;
  2826.          }
  2827. -        else if (self.weapon == IT_GRENADE_LAUNCHER)
  2828. +        else if ((self.weapon == IT_GRENADE_LAUNCHER) || (self.weapon == IT_FIREWALL) || (self.weapon == IT_BOMB))
  2829.          {
  2830.              self.weapon = IT_ROCKET_LAUNCHER;
  2831.              if (self.ammo_rockets < 1)
  2832.                  am = 1;
  2833.          }
  2834. -        else if (self.weapon == IT_ROCKET_LAUNCHER)
  2835. +        else if ((self.weapon == IT_ROCKET_LAUNCHER) || (self.weapon == IT_GIBGUN))
  2836.          {
  2837.              self.weapon = IT_LIGHTNING;
  2838.              if (self.ammo_cells < 1)
  2839.                  am = 1;
  2840.          }
  2841.      
  2842. -        if ( (it & self.weapon) && am == 0)
  2843. +        if ( (self.items & self.weapon) && am == 0)
  2844.          {
  2845.              W_SetCurrentAmmo ();
  2846.              return;
  2847. @@ -1127,98 +1629,168 @@
  2848.  
  2849.  /*
  2850.  ============
  2851. -CycleWeaponReverseCommand
  2852. +ServerflagsCommand
  2853.  
  2854. -Go to the prev weapon with ammo
  2855. +Just for development
  2856.  ============
  2857.  */
  2858. -void() CycleWeaponReverseCommand =
  2859. +void() ServerflagsCommand =
  2860.  {
  2861. -    local    float    it, am;
  2862. -    
  2863. -    it = self.items;
  2864. -    self.impulse = 0;
  2865. +    serverflags = serverflags * 2 + 1;
  2866. +};
  2867.  
  2868. -    while (1)
  2869. -    {
  2870. -        am = 0;
  2871. +void() QuadCheat =
  2872. +{
  2873. +//        if (deathmatch || coop)
  2874. +//                return;
  2875. +    self.super_time = 1;
  2876. +        self.super_damage_finished = time + 9999999;
  2877. +        self.rad_time = 1;
  2878. +        self.radsuit_finished = time + 9999999;
  2879. +        self.invincible_time = 1;
  2880. +        self.invincible_finished = time + 9999999;
  2881. +        self.items = self.items | IT_QUAD | IT_SUIT | 
  2882. +                IT_INVULNERABILITY;
  2883. +        sprint (self,"mega cheat\n");
  2884. +};
  2885.  
  2886. -        if (self.weapon == IT_LIGHTNING)
  2887. -        {
  2888. -            self.weapon = IT_ROCKET_LAUNCHER;
  2889. -            if (self.ammo_rockets < 1)
  2890. -                am = 1;
  2891. -        }
  2892. -        else if (self.weapon == IT_ROCKET_LAUNCHER)
  2893. -        {
  2894. -            self.weapon = IT_GRENADE_LAUNCHER;
  2895. -            if (self.ammo_rockets < 1)
  2896. -                am = 1;
  2897. -        }
  2898. -        else if (self.weapon == IT_GRENADE_LAUNCHER)
  2899. -        {
  2900. -            self.weapon = IT_SUPER_NAILGUN;
  2901. -            if (self.ammo_nails < 2)
  2902. -                am = 1;
  2903. -        }
  2904. -        else if (self.weapon == IT_SUPER_NAILGUN)
  2905. -        {
  2906. -            self.weapon = IT_NAILGUN;
  2907. -            if (self.ammo_nails < 1)
  2908. -                am = 1;
  2909. -        }
  2910. -        else if (self.weapon == IT_NAILGUN)
  2911. -        {
  2912. -            self.weapon = IT_SUPER_SHOTGUN;
  2913. -            if (self.ammo_shells < 2)
  2914. -                am = 1;
  2915. -        }        
  2916. -        else if (self.weapon == IT_SUPER_SHOTGUN)
  2917. -        {
  2918. -            self.weapon = IT_SHOTGUN;
  2919. -            if (self.ammo_shells < 1)
  2920. -                am = 1;
  2921. -        }
  2922. -        else if (self.weapon == IT_SHOTGUN)
  2923. -        {
  2924. -            self.weapon = IT_AXE;
  2925. -        }
  2926. -        else if (self.weapon == IT_AXE)
  2927. -        {
  2928. -            self.weapon = IT_LIGHTNING;
  2929. -            if (self.ammo_cells < 1)
  2930. -                am = 1;
  2931. -        }
  2932. -    
  2933. -        if ( (it & self.weapon) && am == 0)
  2934. -        {
  2935. -            W_SetCurrentAmmo ();
  2936. -            return;
  2937. -        }
  2938. +/*
  2939. +    TELEPORT DROPPER FUNCTIONS:
  2940. +    ADDED BY KTGOW, 08/06/96
  2941. +
  2942. +    DropTeleport assigns the player's "teledrop_dest" to his current
  2943. +    position.
  2944. +
  2945. +    Teleport_to_drop teleports the player to his "teledrop_dest", with
  2946. +    all the usual teleport effects (flash, telefrags, etc).
  2947. +*/
  2948. +
  2949. +void() DropTeleport =
  2950. +{
  2951. +    if(!self.tele_dropped)  {
  2952. +        self.teledrop_dest = spawn();
  2953.      }
  2954. +    self.teledrop_dest.origin = self.origin;
  2955. +    self.teledrop_dest.mangle = self.angles;
  2956. +    self.tele_dropped = 1;
  2957. +        sprint(self, "Teleport destination dropped.\n");
  2958. +};
  2959. +
  2960. +void() Teleport_to_drop =
  2961. +{
  2962. +    local vector org;
  2963. +    if(!self.tele_dropped)  {
  2964. +                sprint(self,"No destination dropped.");
  2965. +        return;
  2966. +    }
  2967. +
  2968. +    // Recreating the "teleport_touch" function here, rather than
  2969. +    // mutilating my data to fit their code. (Sorry)
  2970. +
  2971. +    if(self.health <= 0)  {
  2972. +        return;
  2973. +    }
  2974. +
  2975. +        spawn_tfog (self.teledrop_dest.origin);
  2976. +
  2977. +    makevectors (self.teledrop_dest.mangle);
  2978. +    org = self.teledrop_dest.origin;
  2979.  
  2980. +    spawn_tfog (org);
  2981. +    spawn_tdeath (org,self);
  2982. +
  2983. +    setorigin (self,self.teledrop_dest.origin);
  2984. +    self.angles = self.teledrop_dest.mangle;
  2985. +    self.fixangle = 1;
  2986. +    self.velocity = v_forward * 100;
  2987. +    self.teleport_time = time + 0.5;  // Shorter teleport recovery time
  2988. +    self.flags = self.flags - self.flags & FL_ONGROUND;
  2989.  };
  2990.  
  2991. -/*
  2992. -============
  2993. -ServerflagsCommand
  2994. +void() Teleport_to_bomb =
  2995. +{
  2996. +    local entity oldself,bdest;
  2997.  
  2998. -Just for development
  2999. -============
  3000. -*/
  3001. -void() ServerflagsCommand =
  3002. +    bdest=spawn();
  3003. +    bdest.origin = self.telebomb.origin + '0 0 27';
  3004. +
  3005. +    // Blow up the bomb...
  3006. +    oldself=self;
  3007. +    self=self.telebomb;
  3008. +    GrenadeExplode();
  3009. +    self=oldself;
  3010. +
  3011. +
  3012. +    // Teleport to the bomb's old location
  3013. +
  3014. +    if(self.health <= 0)  {
  3015. +        remove(bdest);
  3016. +        return;
  3017. +    }
  3018. +
  3019. +    // Recreating the "teleport_touch" function here, once again
  3020. +
  3021. +    spawn_tfog (bdest.origin);
  3022. +
  3023. +    spawn_tfog (bdest.origin);
  3024. +    spawn_tdeath (bdest.origin,self);
  3025. +
  3026. +    setorigin (self,bdest.origin);
  3027. +    
  3028. +    self.teleport_time = time + 1;  // Longer teleport recovery time
  3029. +    self.flags = self.flags - self.flags & FL_ONGROUND;
  3030. +
  3031. +    remove(bdest);
  3032. +};
  3033. +
  3034. +void() TeleportBombTouch =
  3035.  {
  3036. -    serverflags = serverflags * 2 + 1;
  3037. +    if (other == self.owner)
  3038. +        return;     // don't explode on owner
  3039. +    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  3040. +    if (self.velocity == '0 0 0')
  3041. +        self.avelocity = '0 0 0';
  3042.  };
  3043.  
  3044. -void() QuadCheat =
  3045. +void() W_FireTeleportBomb =
  3046.  {
  3047. -    if (deathmatch || coop)
  3048. +    local   entity missile, mpuff;
  3049. +    
  3050. +    if(self.telebomb_dropped == 1)  {
  3051.          return;
  3052. -    self.super_time = 1;
  3053. -    self.super_damage_finished = time + 30;
  3054. -    self.items = self.items | IT_QUAD;
  3055. -    dprint ("quad cheat\n");
  3056. +    }
  3057. +
  3058. +    // This uses no ammo.    
  3059. +
  3060. +    self.telebomb = spawn ();
  3061. +    self.telebomb.owner = self;
  3062. +    self.telebomb.movetype = MOVETYPE_BOUNCE;
  3063. +    self.telebomb.solid = SOLID_BBOX;
  3064. +    self.telebomb.classname = "telebomb";
  3065. +        
  3066. +// set missile speed    
  3067. +
  3068. +    makevectors (self.v_angle);
  3069. +
  3070. +    if (self.v_angle_x)
  3071. +        self.telebomb.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  3072. +    else
  3073. +    {
  3074. +        self.telebomb.velocity = aim(self, 10000);
  3075. +        self.telebomb.velocity = missile.velocity * 600;
  3076. +        self.telebomb.velocity_z = 200;
  3077. +    }
  3078. +
  3079. +    self.telebomb.avelocity = '300 300 300';
  3080. +
  3081. +    self.telebomb.angles = vectoangles(self.telebomb.velocity);
  3082. +    
  3083. +    self.telebomb.touch = TeleportBombTouch;
  3084. +//    self.telebomb.think = GrenadeExplode;
  3085. +    
  3086. +    setmodel (self.telebomb, "progs/grenade.mdl");
  3087. +    setsize (self.telebomb, '0 0 0', '0 0 0');        
  3088. +    setorigin (self.telebomb, self.origin);
  3089.  };
  3090.  
  3091.  /*
  3092. @@ -1229,6 +1801,7 @@
  3093.  */
  3094.  void() ImpulseCommands =
  3095.  {
  3096. +        WispImpulses();
  3097.      if (self.impulse >= 1 && self.impulse <= 8)
  3098.          W_ChangeWeapon ();
  3099.  
  3100. @@ -1238,10 +1811,83 @@
  3101.          CycleWeaponCommand ();
  3102.      if (self.impulse == 11)
  3103.          ServerflagsCommand ();
  3104. -    if (self.impulse == 12)
  3105. -        CycleWeaponReverseCommand ();
  3106. +//===============================================
  3107. +        if (self.impulse == 21)
  3108. +                W_ChangeWeapon();
  3109. +        if (self.impulse == 112)
  3110. +                bprint ("Program by Tatter_D!\n");
  3111. +//===============================================
  3112. +    if (self.impulse == 41)
  3113. +        DropTeleport ();
  3114. +    if (self.impulse == 42)  {
  3115. +        if (!self.telebomb_dropped)  {
  3116. +           W_FireTeleportBomb ();
  3117. +         self.telebomb_dropped=1;
  3118. +          } else {
  3119. +         Teleport_to_bomb();
  3120. +         self.telebomb_dropped=0;
  3121. +        }
  3122. +    }
  3123. +    if (self.impulse == 43)
  3124. +        Teleport_to_drop ();
  3125. +
  3126. +    
  3127. +    // PATCH FOR BOUNCERS
  3128. +    if (self.impulse == 20)
  3129. +        W_LaunchBouncer ();
  3130. +    if (self.impulse == 21)
  3131. +        W_FireBomb ();
  3132. +        if (self.impulse == 150)        // experimental
  3133. +                feign ();
  3134. +    
  3135. +// *************************************************************************
  3136. +// **                                          **
  3137. +// ** M U L T I S K I N  1.1  (start)                                     **
  3138. +// **                                      **
  3139. +// *************************************************************************
  3140. +
  3141. +
  3142. +    if ((self.impulse == 200) || (self.impulse == 201))
  3143. +    {
  3144. +        if (self.impulse == 200)
  3145. +        {
  3146. +        self.skin = self.skin + 1;
  3147. +        if (self.skin == 19) self.skin = 0;
  3148. +        } else
  3149. +        if (self.impulse == 201)
  3150. +        {
  3151. +        self.skin = self.skin - 1;
  3152. +        if (self.skin == -1) self.skin = 19;
  3153. +        }
  3154. +        if (self.skin == 0) centerprint(self, "SKIN: Quake himself (1)"); else
  3155. +        if (self.skin == 1) centerprint(self, "SKIN: Duke Nukem 3d (2)"); else
  3156. +        if (self.skin == 2) centerprint(self, "SKIN: Mr. Toad (3)"); else
  3157. +        if (self.skin == 3) centerprint(self, "SKIN: the Stormtrooper (4)"); else
  3158. +        if (self.skin == 4) centerprint(self, "SKIN: Max (5)"); else
  3159. +        if (self.skin == 5) centerprint(self, "SKIN: the Terminator (6)"); else
  3160. +        if (self.skin == 6) centerprint(self, "SKIN: Judge Dredd (7)"); else
  3161. +        if (self.skin == 7) centerprint(self, "SKIN: Camouflaged soldier (8)"); else
  3162. +        if (self.skin == 8) centerprint(self, "SKIN: Captain Picard (9)"); else
  3163. +        if (self.skin == 9) centerprint(self, "SKIN: the Wizzard (10)"); else
  3164. +        if (self.skin == 10) centerprint(self,"SKIN: the Predator (11)"); else
  3165. +        if (self.skin == 11) centerprint(self,"SKIN: Skeleton (12)"); else
  3166. +        if (self.skin == 12) centerprint(self,"SKIN: Wan-Fu (13)"); else
  3167. +        if (self.skin == 13) centerprint(self,"SKIN: Henry Rollins (14)"); else
  3168. +        if (self.skin == 14) centerprint(self,"SKIN: He-Man (15)"); else
  3169. +        if (self.skin == 15) centerprint(self,"SKIN: Boba (16)"); else
  3170. +        if (self.skin == 16) centerprint(self,"SKIN: Superman (17)"); else
  3171. +        if (self.skin == 17) centerprint(self,"SKIN: NYPD Cop (18)"); else
  3172. +        if (self.skin == 18) centerprint(self,"SKIN: Red/Yellow women dude (19)");
  3173. +    }
  3174. +
  3175. +// *************************************************************************
  3176. +// **                                          **
  3177. +// ** M U L T I S K I N  1.1  (end)                                       **
  3178. +// **                                      **
  3179. +// *************************************************************************
  3180. +
  3181.  
  3182. -    if (self.impulse == 255)
  3183. +        if (self.impulse == 255)
  3184.          QuadCheat ();
  3185.          
  3186.      self.impulse = 0;
  3187. @@ -1290,3 +1936,244 @@
  3188.  };
  3189.  
  3190.  
  3191. +/***********************************************************************************
  3192. +================
  3193. +W_FireBomb
  3194. +================
  3195. +************************************************************************************/
  3196. +void() W_FireBomb =
  3197. +{
  3198. +    local   entity missile, mpuff;
  3199. +
  3200. +    if ((self.ammo_rockets < 5) || (self.weapon != IT_BOMB))
  3201. +    {
  3202. +        return;
  3203. +    }
  3204. +
  3205. +
  3206. +    if (bombtimer >0 )
  3207. +    {
  3208. +        return;
  3209. +    }
  3210. +    else     bombtimer=1.5;
  3211. +
  3212. +
  3213. +    self.currentammo = self.ammo_rockets = self.ammo_rockets - 5;
  3214. +    
  3215. +
  3216. +
  3217. +    self.punchangle_x = -10;
  3218. +
  3219. +    missile = spawn ();
  3220. +    missile.owner = self;
  3221. +    missile.movetype = MOVETYPE_FLY;
  3222. +    missile.solid = SOLID_TRIGGER;
  3223. +    missile.classname = "Bomb";
  3224. +        
  3225. +// set missile speed    
  3226. +
  3227. +    makevectors (self.v_angle);
  3228. +
  3229. +
  3230. +    missile.velocity= '0 0 0';
  3231. +    missile.avelocity= '0 0 0';
  3232. +    
  3233. +    missile.touch = BombTouch;
  3234. +    
  3235. +// set missile duration
  3236. +    missile.nextthink = time + 0.25;
  3237. +    missile.think = BombTime;
  3238. +
  3239. +    setmodel (missile, "progs/grenade.mdl");
  3240. +    setsize (missile, '-48 -48 -4', '48 48 4');            
  3241. +    setorigin (missile, self.origin - '0 0 20');
  3242. +//    sprint(self,"Better stay the hell clear now\n");
  3243. +};
  3244. +
  3245. +void() BombTime =
  3246. +{
  3247. +    bombtimer = bombtimer - 0.25;
  3248. +    if (bombtimer)
  3249. +        {
  3250. +        if (bombtimer == 0.5) self.velocity='0 0 24';
  3251. +        sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  3252. +        self.nextthink = time + 0.25;
  3253. +        self.think = BombTime;
  3254. +        } 
  3255. +    else
  3256. +    {
  3257. +        self.nextthink = time + 180;
  3258. +        self.think = BecomeExplosion;
  3259. +        self.classname = "ArmedBomb";
  3260. +        self.velocity='0 0 0';
  3261. +        self.avelocity='0 800 800';
  3262. +        
  3263. +        self.health = 20;
  3264. +        self.th_die = BombExplode;
  3265. +        self.takedamage = DAMAGE_AIM;
  3266. +
  3267. +    }
  3268. +};
  3269. +
  3270. +void() BombTouch =
  3271. +{
  3272. +    if (other.takedamage && (self.classname == "ArmedBomb") && (other.classname != "ArmedBomb"))
  3273. +    {
  3274. +        BombExplode();
  3275. +        return;
  3276. +    }
  3277. +
  3278. +};
  3279. +
  3280. +void() BombExplode =
  3281. +{
  3282. +    T_RadiusDamage (self, self.owner, 120, world);
  3283. +    T_RadiusDamage (self, self.owner, 120, world);
  3284. +
  3285. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3286. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  3287. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  3288. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  3289. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  3290. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3291. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  3292. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  3293. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  3294. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  3295. +
  3296. +    BombExplosion ();
  3297. +};
  3298. +
  3299. +void() BombExplosion =
  3300. +{
  3301. +    sound (self, CHAN_AUTO, "items/damage2.wav", 1, ATTN_NORM);
  3302. +    self.movetype = MOVETYPE_NONE;
  3303. +    self.velocity = '0 0 0';
  3304. +    self.touch = SUB_Null;
  3305. +    setmodel (self, "progs/s_explod.spr");
  3306. +    self.solid = SOLID_NOT;
  3307. +    s_explode1 ();
  3308. +};
  3309. +
  3310. +void() ShrapnelExplode =
  3311. +{
  3312. +    T_RadiusDamage (self, self.owner, 120, world);
  3313. +
  3314. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3315. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  3316. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  3317. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  3318. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  3319. +
  3320. +    BecomeExplosion ();
  3321. +};
  3322. +
  3323. +void() GIBExplode =
  3324. +{
  3325. +    local entity loser;
  3326. +    self.wait = self.wait - 1;
  3327. +    loser = self.trigger_field;
  3328. +
  3329. +    if ((self.wait == 30) || (self.wait == 20) || (self.wait == 10))     sound (self, CHAN_WEAPON, "player/tornoff2.wav", 1, ATTN_NORM);    
  3330. +    if (((self.wait == 35) || (self.wait == 25) || (self.wait == 15)) && (loser.classname == "player"))     sound (self, CHAN_WEAPON, "player/lburn1.wav", 1, ATTN_NORM);    
  3331. +
  3332. +    if ((!self.wait) || (loser.health<=10))
  3333. +    {
  3334. +    T_RadiusDamage (self, self.owner, 120, world);
  3335. +
  3336. +    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3337. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  3338. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  3339. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  3340. +    WriteCoord (MSG_BROADCAST, self.origin_z);
  3341. +
  3342. +    BecomeExplosion ();
  3343. +    return;
  3344. +    }
  3345. +
  3346. +    
  3347. +    T_Damage (loser, self, self.owner, 2.5 );
  3348. +    spawn_touchblood (30);
  3349. +
  3350. +    self.origin = loser.origin + '0 0 12';
  3351. +    self.nextthink = time + 0.05;
  3352. +    self.think = GIBExplode;
  3353. +        
  3354. +};
  3355. +
  3356. +void() T_GIBTouch =
  3357. +{
  3358. +    local float     damg;
  3359. +
  3360. +    if (other == self.owner)
  3361. +        return;         // don't explode on owner
  3362. +
  3363. +    if (pointcontents(self.origin) == CONTENT_SKY)
  3364. +    {
  3365. +        remove(self);
  3366. +        return;
  3367. +    }
  3368. +
  3369. +
  3370. +    
  3371. +    if (other.takedamage)
  3372. +    {
  3373. +        sound (self, CHAN_WEAPON, "player/tornoff2.wav", 1, ATTN_NORM);    
  3374. +        self.trigger_field = other;
  3375. +        self.origin = other.origin + '0 0 12';
  3376. +        self.wait = 40;
  3377. +
  3378. +        self.nextthink = time + 0.05;
  3379. +        self.think = GIBExplode;
  3380. +        self.movetype = MOVETYPE_NOCLIP;
  3381. +        self.velocity = '0 0 0' ;
  3382. +        self.avelocity = '0 0 1000';
  3383. +        return;
  3384. +    }
  3385. +    sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);  // bounce sound
  3386. +//    remove(self);
  3387. +    self.nextthink = time + 0.3;
  3388. +    self.think = SUB_Remove;
  3389. +    self.movetype = MOVETYPE_NOCLIP;
  3390. +    self.velocity = ' 0 0 0';
  3391. +    self.avelocity = '0 0 1000';
  3392. +};
  3393. +
  3394. +
  3395. +
  3396. +/*
  3397. +================
  3398. +W_FireGIBGUN
  3399. +================
  3400. +*/
  3401. +void() W_FireGIBGUN =
  3402. +{
  3403. +    local   entity missile, mpuff;
  3404. +    
  3405. +    self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  3406. +    
  3407. +    sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  3408. +
  3409. +    self.punchangle_x = -2;
  3410. +
  3411. +    missile = spawn ();
  3412. +    missile.owner = self;
  3413. +    missile.movetype = MOVETYPE_FLYMISSILE;
  3414. +    missile.solid = SOLID_BBOX;
  3415. +        
  3416. +// set missile speed    
  3417. +
  3418. +    makevectors (self.v_angle);
  3419. +    missile.velocity = aim(self, 1000);
  3420. +    missile.velocity = missile.velocity * 1000;
  3421. +    missile.angles = vectoangles(missile.velocity);
  3422. +    
  3423. +    missile.touch = T_GIBTouch;
  3424. +    
  3425. +// set missile duration
  3426. +    missile.nextthink = time + 5;
  3427. +    missile.think = SUB_Remove;
  3428. +    setmodel (missile, "progs/missile.mdl");
  3429. +    setsize (missile, '0 0 0', '0 0 0');            
  3430. +    setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  3431. +};
  3432. diff -ur --new-file v106qc/wisp.qc kalq-src/wisp.qc
  3433. --- v106qc/wisp.qc    Thu Jan  1 00:00:00 1970
  3434. +++ kalq-src/wisp.qc    Fri Oct 25 06:01:50 1996
  3435. @@ -0,0 +1,447 @@
  3436. +
  3437. +void () Wisp_Die;
  3438. +void (entity attacker, float damage) Wisp_Pain;
  3439. +void () WispImpulses;
  3440. +void () WispToggleView;
  3441. +void () WispToggleHalt;
  3442. +void () WispThink;
  3443. +void () WispAttack;
  3444. +void () WispApproach;
  3445. +void () WispHunt;
  3446. +entity () WispFindTarget;
  3447. +void () WispReset;
  3448. +void () WispActivate;
  3449. +void () WispDeactivate;
  3450. +void () WispToggle;
  3451. +void (entity tgt) WispFire;
  3452. +void () WispRecall;
  3453. +
  3454. +void (vector p1, vector p2, entity from, float damage) LightningDamage;
  3455. +void () BecomeExplosion;
  3456. +
  3457. +void (vector org) spawn_tfog;
  3458. +
  3459. +void () Wisp_Die =
  3460. +{
  3461. +        if(self.owner.wisp_view==TRUE)
  3462. +                WispToggleView();
  3463. +        sprint(self.owner,"Wisp has died!\n");
  3464. +        self.owner.wisp_flag=FALSE;
  3465. +        // Detonate wisp when it dies
  3466. +        WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3467. +    WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  3468. +    WriteCoord (MSG_BROADCAST, self.origin_x);
  3469. +    WriteCoord (MSG_BROADCAST, self.origin_y);
  3470. +        WriteCoord (MSG_BROADCAST, self.origin_z);
  3471. +        BecomeExplosion();
  3472. +};
  3473. +
  3474. +void (entity attacker, float damage) Wisp_Pain =
  3475. +{
  3476. +        local string stemp;
  3477. +        sprint(self.owner,"Wisp: hit by ");
  3478. +        if(attacker.classname=="player")
  3479. +                sprint(self.owner,attacker.netname);
  3480. +        else
  3481. +                sprint(self.owner,attacker.classname);
  3482. +        stemp=ftos(self.health);
  3483. +        sprint(self.owner,", health ");
  3484. +        sprint(self.owner,stemp);
  3485. +        sprint(self.owner,"\n");
  3486. +};
  3487. +
  3488. +void () WispImpulses =
  3489. +{
  3490. +        if(self.impulse==100)           // Summon/banish wisp
  3491. +                WispToggle();
  3492. +        if(self.impulse==101)           // Teleport wisp to self
  3493. +                WispRecall();
  3494. +        if(self.impulse==102)           // Freeze/unfreeze wisp
  3495. +                WispToggleHalt();
  3496. +        if(self.impulse==103)           // Hitch a ride/drop off
  3497. +                WispToggleView();
  3498. +};
  3499. +
  3500. +void () WispToggleView =
  3501. +{
  3502. +        if(self.wisp_flag==FALSE)
  3503. +        {
  3504. +                sprint(self,"Wisp hasn't been summoned.\n");
  3505. +                return;
  3506. +        }
  3507. +        if(self.wisp_view==FALSE)
  3508. +        {
  3509. +                setorigin(self,self.wisp.origin);
  3510. +                self.movetype=MOVETYPE_FLY;
  3511. +                self.wisp_view=TRUE;
  3512. +        }
  3513. +        else
  3514. +        {
  3515. +                self.movetype=MOVETYPE_WALK;
  3516. +                self.wisp_view=FALSE;
  3517. +        }
  3518. +};
  3519. +
  3520. +void () WispToggleHalt =
  3521. +{
  3522. +        if(self.wisp_state==WISP_HALT)
  3523. +                self.wisp_state=WISP_HUNT;
  3524. +        else
  3525. +        {
  3526. +                self.wisp_state=WISP_HALT;
  3527. +                self.wisp.velocity='0 0 0';
  3528. +        }
  3529. +};
  3530. +
  3531. +void () WispThink =
  3532. +{
  3533. +        local float ftemp;
  3534. +        if(self.owner.wisp_stuck==TRUE)
  3535. +        {       // if wisp was unstuck, restore bounding box
  3536. +                ftemp=vlen(self.origin-self.owner.wisp_porg);
  3537. +                if(ftemp>=10)
  3538. +                {
  3539. +                        setsize(self,'-4 -4 -4','4 4 4');
  3540. +                        self.owner.wisp_stuck=FALSE;
  3541. +                }
  3542. +        }
  3543. +        if(self.owner.wisp_porg==self.origin && self.owner.wisp_state!=WISP_HALT)
  3544. +        {       // if wisp is stuck, try to unstuck by eliminating bounding box
  3545. +                setsize(self,'0 0 0','0 0 0');
  3546. +                self.owner.wisp_stuck=TRUE;
  3547. +//                sprint(self.owner,"UNSTUCKING WISP\n");
  3548. +        }
  3549. +        self.owner.wisp_porg=self.origin;       // save previous origin for stuck detection
  3550. +        if(self.owner.wisp_view==TRUE)
  3551. +        {       // update position after wisp if being carried
  3552. +                setorigin(self.owner,self.origin);
  3553. +        }
  3554. +        if(self.owner.wisp_state==WISP_HUNT)
  3555. +                WispHunt();
  3556. +        else
  3557. +                if(self.owner.wisp_state==WISP_APPROACH)
  3558. +                        WispApproach();
  3559. +                else
  3560. +                        if(self.owner.wisp_state==WISP_ATTACK)
  3561. +                                WispAttack();
  3562. +
  3563. +        self.nextthink=time+0.1;
  3564. +        self.think=WispThink;
  3565. +};
  3566. +
  3567. +void () WispAttack =
  3568. +{
  3569. +        if(self.enemy.health<1 || !(self.enemy))
  3570. +                self.owner.wisp_state=WISP_HUNT;        // no valid enemy, go hunt
  3571. +        else
  3572. +        {
  3573. +                traceline(self.origin,self.enemy.origin,TRUE,self);
  3574. +                if(trace_fraction==1.0)
  3575. +                {
  3576. +                        self.velocity='0 0 0';
  3577. +                        WispFire(self.enemy);
  3578. +                }
  3579. +                else
  3580. +                        self.owner.wisp_state=WISP_HUNT;        // enemy not in sight, go hunt
  3581. +        }
  3582. +        self.think=WispThink;
  3583. +        self.nextthink=time+0.1;
  3584. +};
  3585. +
  3586. +void () WispApproach =
  3587. +{
  3588. +        local float ftemp;
  3589. +        local vector vtemp,dir;
  3590. +        if(self.enemy != world)
  3591. +        {
  3592. +                traceline(self.origin,self.enemy.origin,TRUE,self);
  3593. +                if(trace_fraction==1.0 && !(self.enemy.health<1 || !(self.enemy)))
  3594. +                {
  3595. +                        ftemp=vlen(self.enemy.origin-self.origin);
  3596. +                        if(ftemp>300)
  3597. +                        {       // far from enemy, approach
  3598. +                                vtemp=self.enemy.origin+'0 0 10';
  3599. +                                dir=normalize(vtemp-self.origin);
  3600. +                                self.velocity=dir*200;
  3601. +                                self.angles=vectoangles(self.velocity);
  3602. +                        }
  3603. +                        else    // near to enemy, attack
  3604. +                                self.owner.wisp_state=WISP_ATTACK;
  3605. +                }
  3606. +                else    // no valid enemy in sight, go hunt
  3607. +                        self.owner.wisp_state=WISP_HUNT;
  3608. +        }
  3609. +        else    // won't attack the world, go hunt
  3610. +                self.owner.wisp_state=WISP_HUNT;
  3611. +};
  3612. +
  3613. +void () WispHunt =
  3614. +{
  3615. +        local float r,mf;
  3616. +        local float dist=300;
  3617. +        local float offset;
  3618. +        local float spd;
  3619. +        local vector ang,sel;
  3620. +
  3621. +        self.enemy=WispFindTarget();
  3622. +        if(self.enemy)
  3623. +        {       // enemy found, approach
  3624. +                self.owner.wisp_state=1;
  3625. +                return;
  3626. +        }
  3627. +        makevectors(self.angles);
  3628. +        traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3629. +        if(trace_fraction<1.0)
  3630. +        {       // approaching obstacle
  3631. +                offset=90-trace_fraction*80;
  3632. +                spd=(trace_fraction)*200;       // reduce speed as we get nearer
  3633. +                if(trace_fraction*dist<=50)
  3634. +                {       // wisp is very near obstacle, panic move (90 degrees)
  3635. +                        offset=90;
  3636. +                        sprint(self.owner,"Wisp halted!\n");
  3637. +                }
  3638. +                mf=0;
  3639. +                ang=self.angles;
  3640. +                ang_x=anglemod(ang_x+offset);
  3641. +                makevectors(ang);
  3642. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3643. +                if(trace_fraction>mf)
  3644. +                {
  3645. +                        mf=trace_fraction;
  3646. +                        sel=ang;
  3647. +                }
  3648. +                ang=self.angles;
  3649. +                ang_x=anglemod(ang_x-offset);
  3650. +                makevectors(ang);
  3651. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3652. +                if(trace_fraction>mf)
  3653. +                {
  3654. +                        mf=trace_fraction;
  3655. +                        sel=ang;
  3656. +                }
  3657. +                ang=self.angles;
  3658. +                ang_x=anglemod(ang_x+offset);
  3659. +                ang_y=anglemod(ang_y+offset);
  3660. +                makevectors(ang);
  3661. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3662. +                if(trace_fraction>mf)
  3663. +                {
  3664. +                        mf=trace_fraction;
  3665. +                        sel=ang;
  3666. +                }
  3667. +                ang=self.angles;
  3668. +                ang_x=anglemod(ang_x+offset);
  3669. +                ang_y=anglemod(ang_y-offset);
  3670. +                makevectors(ang);
  3671. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3672. +                if(trace_fraction>mf)
  3673. +                {
  3674. +                        mf=trace_fraction;
  3675. +                        sel=ang;
  3676. +                }
  3677. +                ang=self.angles;
  3678. +                ang_y=anglemod(ang_y+offset);
  3679. +                makevectors(ang);
  3680. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3681. +                if(trace_fraction>mf)
  3682. +                {
  3683. +                        mf=trace_fraction;
  3684. +                        sel=ang;
  3685. +                }
  3686. +                ang=self.angles;
  3687. +                ang_y=anglemod(ang_y-offset);
  3688. +                makevectors(ang);
  3689. +                        traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3690. +                if(trace_fraction>mf)
  3691. +                {
  3692. +                        mf=trace_fraction;
  3693. +                        sel=ang;
  3694. +                }
  3695. +                ang=self.angles;
  3696. +                ang_x=anglemod(ang_x-offset);
  3697. +                ang_y=anglemod(ang_y+offset);
  3698. +                makevectors(ang);
  3699. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3700. +                if(trace_fraction>mf)
  3701. +                {
  3702. +                        mf=trace_fraction;
  3703. +                        sel=ang;
  3704. +                }
  3705. +                ang=self.angles;
  3706. +                ang_x=anglemod(ang_x-offset);
  3707. +                ang_y=anglemod(ang_y+offset);
  3708. +                makevectors(ang);
  3709. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3710. +                if(trace_fraction>mf)
  3711. +                {
  3712. +                        mf=trace_fraction;
  3713. +                        sel=ang;
  3714. +                }
  3715. +                ang=self.angles;
  3716. +                makevectors(ang);
  3717. +                traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  3718. +                if(trace_fraction>mf)
  3719. +                {
  3720. +                        mf=trace_fraction;
  3721. +                        sel=ang;
  3722. +                }
  3723. +                self.angles=sel;
  3724. +                makevectors(sel);
  3725. +                self.velocity=v_forward*spd;
  3726. +        }
  3727. +        else
  3728. +        {       // no obstacle in sight, change course a little, but unpredictably
  3729. +                ang=self.angles;
  3730. +                r=random()*10 - 5;
  3731. +                ang_x=anglemod(ang_x+r);
  3732. +                r=random()*10 - 5;
  3733. +                ang_y=anglemod(ang_y+r);
  3734. +                self.angles=ang;
  3735. +                makevectors(ang);
  3736. +                self.velocity=v_forward*200;
  3737. +        }
  3738. +        self.think=WispThink;
  3739. +        self.nextthink=time+0.1;
  3740. +};
  3741. +
  3742. +entity () WispFindTarget =
  3743. +{       // Find nearest valid target
  3744. +    local entity head, selected;
  3745. +    local float dist;
  3746. +    dist = 100000;
  3747. +    selected = world;
  3748. +    head = findradius(self.origin, 100000);
  3749. +    while(head)
  3750. +    {
  3751. +                if( (head.health > 1) && (head != self) && (head != self.owner) && head.classname != "door" && head.classname != "monster_zombie")
  3752. +        {
  3753. +            traceline(self.origin,head.origin,TRUE,self);
  3754. +            if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) )
  3755. +            {
  3756. +                selected = head;
  3757. +                dist = vlen(head.origin - self.origin);
  3758. +            }
  3759. +        }        
  3760. +        head = head.chain;
  3761. +    }
  3762. +        if (selected != world)
  3763. +    {
  3764. +                sprint (self.owner,"Wisp: attacking ");
  3765. +        if (selected.classname == "player")
  3766. +                        sprint (self.owner,selected.netname);
  3767. +        else
  3768. +            sprint (self.owner,selected.classname);
  3769. +        sprint (self.owner,"\n");
  3770. +    }
  3771. +    return selected;
  3772. +};
  3773. +
  3774. +void () WispReset =
  3775. +{
  3776. +        self.wisp_state=WISP_HUNT;
  3777. +        self.wisp.enemy=world;
  3778. +        self.wisp.angles=self.angles;
  3779. +};
  3780. +
  3781. +void () WispActivate =
  3782. +{
  3783. +        local entity newwisp;
  3784. +        newwisp=spawn();
  3785. +        newwisp.solid=SOLID_BBOX;
  3786. +        newwisp.movetype=MOVETYPE_FLY;
  3787. +        newwisp.classname="wisp";
  3788. +        newwisp.owner=self;
  3789. +
  3790. +        self.wisp=newwisp;
  3791. +        self.wisp_flag=TRUE;
  3792. +        newwisp.th_pain=Wisp_Pain;
  3793. +        newwisp.th_die=Wisp_Die;
  3794. +        newwisp.takedamage=TRUE;
  3795. +        self.wisp_stuck=FALSE;
  3796. +        self.wisp_porg='0 0 0';
  3797. +        self.wisp_view=FALSE;
  3798. +        WispReset();
  3799. +        if (deathmatch || coop)
  3800. +        {
  3801. +                newwisp.health = 110;
  3802. +            setmodel(newwisp,"progs/eyes.mdl");
  3803. +        }
  3804. +        else
  3805. +        {
  3806. +                newwisp.health = 60;
  3807. +                    setmodel(newwisp,"progs/lavaball.mdl");
  3808. +        }
  3809. +        newwisp.takedamage=DAMAGE_AIM;
  3810. +
  3811. +/*
  3812. +//      Moved to the If's above for Deathmatch play! :)
  3813. +//      By Kenneth Livingston   -=CT=-KALWeb  (underhill@geocities.com
  3814. +//                                or underhill@netpass.com)
  3815. +        setmodel(newwisp,"progs/lavaball.mdl");
  3816. +        setmodel(newwisp,"progs/eyes.mdl");
  3817. +*/
  3818. +
  3819. +        setsize(newwisp,'-4 -4 -4','4 4 4');
  3820. +        setorigin(newwisp,self.origin+'0 0 16');
  3821. +
  3822. +        spawn_tfog(newwisp.origin);
  3823. +        sprint(self,"Wisp summoned!\n");
  3824. +        newwisp.nextthink=time+0.1;
  3825. +        newwisp.think=WispThink;
  3826. +};
  3827. +
  3828. +void () WispDeactivate =
  3829. +{
  3830. +        if(self.owner.wisp_view==TRUE)
  3831. +                WispToggleView();
  3832. +        spawn_tfog(self.wisp.origin);
  3833. +        self.wisp.nextthink=time+0.1;
  3834. +        self.wisp.think=SUB_Remove;
  3835. +        self.wisp_flag=FALSE;
  3836. +        sprint(self,"Wisp Banished!\n");
  3837. +
  3838. +};
  3839. +
  3840. +void () WispToggle =
  3841. +{
  3842. +        if(self.wisp_flag)
  3843. +                WispDeactivate();
  3844. +        else
  3845. +                WispActivate();
  3846. +};
  3847. +
  3848. +void (entity tgt) WispFire =
  3849. +{       // Fire lightning at enemy
  3850. +        local vector org;
  3851. +        sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  3852. +        org=self.origin;
  3853. +
  3854. +        WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  3855. +    WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  3856. +    WriteEntity (MSG_BROADCAST, self);
  3857. +    WriteCoord (MSG_BROADCAST, org_x);
  3858. +    WriteCoord (MSG_BROADCAST, org_y);
  3859. +    WriteCoord (MSG_BROADCAST, org_z);
  3860. +    WriteCoord (MSG_BROADCAST, trace_endpos_x);
  3861. +    WriteCoord (MSG_BROADCAST, trace_endpos_y);
  3862. +    WriteCoord (MSG_BROADCAST, trace_endpos_z);
  3863. +
  3864. +        LightningDamage(org,self.enemy.origin,self,5);
  3865. +};
  3866. +
  3867. +void () WispRecall =
  3868. +{       // Teleport wisp to self
  3869. +        if(!self.wisp_flag)
  3870. +        {
  3871. +                sprint(self,"Wisp hasn't been summoned.\n");
  3872. +                return;
  3873. +        }
  3874. +        spawn_tfog(self.wisp.origin);
  3875. +        setorigin(self.wisp,self.origin+'0 0 16');
  3876. +        spawn_tfog(self.wisp.origin);
  3877. +        self.wisp_stuck=FALSE;
  3878. +        self.wisp_porg='0 0 0';
  3879. +        self.wisp.think=WispThink;
  3880. +        self.wisp.nextthink=time+0.1;
  3881. +        WispReset();
  3882. +};
  3883. diff -ur --new-file v106qc/world.qc kalq-src/world.qc
  3884. --- v106qc/world.qc    Thu Sep 26 11:15:40 1996
  3885. +++ kalq-src/world.qc    Tue Oct 22 15:02:20 1996
  3886. @@ -173,6 +173,7 @@
  3887.  {
  3888.      lastspawn = world;
  3889.      InitBodyQue ();
  3890. +    item_to_exchange = world;
  3891.  
  3892.  // custom map attributes
  3893.      if (self.model == "maps/e1m8.bsp")
  3894. @@ -180,6 +181,7 @@
  3895.      else
  3896.          cvar_set ("sv_gravity", "800");
  3897.  
  3898. +    
  3899.  // the area based ambient sounds MUST be the first precache_sounds
  3900.  
  3901.  // player precaches    
  3902. @@ -271,6 +273,7 @@
  3903.      precache_model ("progs/v_shot2.mdl");
  3904.      precache_model ("progs/v_nail2.mdl");
  3905.      precache_model ("progs/v_rock2.mdl");
  3906. +        precache_model ("progs/v_spike.mdl");           // for grappling hook
  3907.  
  3908.      precache_model ("progs/bolt.mdl");        // for lightning gun
  3909.      precache_model ("progs/bolt2.mdl");        // for lightning gun
  3910. @@ -281,6 +284,8 @@
  3911.      precache_model ("progs/grenade.mdl");
  3912.      precache_model ("progs/spike.mdl");
  3913.      precache_model ("progs/s_spike.mdl");
  3914. +//      precache_model ("progs/star.mdl");
  3915. +//      precache_model ("progs/bit.mdl");
  3916.  
  3917.      precache_model ("progs/backpack.mdl");
  3918.  
  3919.