home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq097 / wisp.qc < prev    next >
Encoding:
Text File  |  1996-08-31  |  13.8 KB  |  431 lines

  1.  
  2. void () Wisp_Die;
  3. void (entity attacker, float damage) Wisp_Pain;
  4. void () WispImpulses;
  5. void () WispToggleView;
  6. void () WispToggleHalt;
  7. void () WispThink;
  8. void () WispAttack;
  9. void () WispApproach;
  10. void () WispHunt;
  11. entity () WispFindTarget;
  12. void () WispReset;
  13. void () WispActivate;
  14. void () WispDeactivate;
  15. void () WispToggle;
  16. void (entity tgt) WispFire;
  17. void () WispRecall;
  18.  
  19. void (vector p1, vector p2, entity from, float damage) LightningDamage;
  20. void () BecomeExplosion;
  21.  
  22. void (vector org) spawn_tfog;
  23.  
  24. void () Wisp_Die =
  25. {
  26.         if(self.owner.wisp_view==TRUE)
  27.                 WispToggleView();
  28.         sprint(self.owner,"Wisp has died!\n");
  29.         self.owner.wisp_flag=FALSE;
  30.         // Detonate wisp when it dies
  31.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  32.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  33.     WriteCoord (MSG_BROADCAST, self.origin_x);
  34.     WriteCoord (MSG_BROADCAST, self.origin_y);
  35.         WriteCoord (MSG_BROADCAST, self.origin_z);
  36.         BecomeExplosion();
  37. };
  38.  
  39. void (entity attacker, float damage) Wisp_Pain =
  40. {
  41.         local string stemp;
  42.         sprint(self.owner,"Wisp: hit by ");
  43.         if(attacker.classname=="player")
  44.                 sprint(self.owner,attacker.netname);
  45.         else
  46.                 sprint(self.owner,attacker.classname);
  47.         stemp=ftos(self.health);
  48.         sprint(self.owner,", health ");
  49.         sprint(self.owner,stemp);
  50.         sprint(self.owner,"\n");
  51. };
  52.  
  53. void () WispImpulses =
  54. {
  55.         if(self.impulse==100)           // Summon/banish wisp
  56.                 WispToggle();
  57.         if(self.impulse==101)           // Teleport wisp to self
  58.                 WispRecall();
  59.         if(self.impulse==102)           // Freeze/unfreeze wisp
  60.                 WispToggleHalt();
  61.         if(self.impulse==103)           // Hitch a ride/drop off
  62.                 WispToggleView();
  63. };
  64.  
  65. void () WispToggleView =
  66. {
  67.         if(self.wisp_flag==FALSE)
  68.         {
  69.                 sprint(self,"Wisp hasn't been summoned.\n");
  70.                 return;
  71.         }
  72.         if(self.wisp_view==FALSE)
  73.         {
  74.                 setorigin(self,self.wisp.origin);
  75.                 self.movetype=MOVETYPE_FLY;
  76.                 self.wisp_view=TRUE;
  77.         }
  78.         else
  79.         {
  80.                 self.movetype=MOVETYPE_WALK;
  81.                 self.wisp_view=FALSE;
  82.         }
  83. };
  84.  
  85. void () WispToggleHalt =
  86. {
  87.         if(self.wisp_state==WISP_HALT)
  88.                 self.wisp_state=WISP_HUNT;
  89.         else
  90.         {
  91.                 self.wisp_state=WISP_HALT;
  92.                 self.wisp.velocity='0 0 0';
  93.         }
  94. };
  95.  
  96. void () WispThink =
  97. {
  98.         local float ftemp;
  99.         if(self.owner.wisp_stuck==TRUE)
  100.         {       // if wisp was unstuck, restore bounding box
  101.                 ftemp=vlen(self.origin-self.owner.wisp_porg);
  102.                 if(ftemp>=10)
  103.                 {
  104.                         setsize(self,'-4 -4 -4','4 4 4');
  105.                         self.owner.wisp_stuck=FALSE;
  106.                 }
  107.         }
  108.         if(self.owner.wisp_porg==self.origin && self.owner.wisp_state!=WISP_HALT)
  109.         {       // if wisp is stuck, try to unstuck by eliminating bounding box
  110.                 setsize(self,'0 0 0','0 0 0');
  111.                 self.owner.wisp_stuck=TRUE;
  112. //                sprint(self.owner,"UNSTUCKING WISP\n");
  113.         }
  114.         self.owner.wisp_porg=self.origin;       // save previous origin for stuck detection
  115.         if(self.owner.wisp_view==TRUE)
  116.         {       // update position after wisp if being carried
  117.                 setorigin(self.owner,self.origin);
  118.         }
  119.         if(self.owner.wisp_state==WISP_HUNT)
  120.                 WispHunt();
  121.         else
  122.                 if(self.owner.wisp_state==WISP_APPROACH)
  123.                         WispApproach();
  124.                 else
  125.                         if(self.owner.wisp_state==WISP_ATTACK)
  126.                                 WispAttack();
  127.         self.nextthink=time+0.1;
  128.         self.think=WispThink;
  129. };
  130.  
  131. void () WispAttack =
  132. {
  133.         if(self.enemy.health<1 || !(self.enemy))
  134.                 self.owner.wisp_state=WISP_HUNT;        // no valid enemy, go hunt
  135.         else
  136.         {
  137.                 traceline(self.origin,self.enemy.origin,TRUE,self);
  138.                 if(trace_fraction==1.0)
  139.                 {
  140.                         self.velocity='0 0 0';
  141.                         WispFire(self.enemy);
  142.                 }
  143.                 else
  144.                         self.owner.wisp_state=WISP_HUNT;        // enemy not in sight, go hunt
  145.         }
  146.         self.think=WispThink;
  147.         self.nextthink=time+0.1;
  148. };
  149.  
  150. void () WispApproach =
  151. {
  152.         local float ftemp;
  153.         local vector vtemp,dir;
  154.         if(self.enemy != world)
  155.         {
  156.                 traceline(self.origin,self.enemy.origin,TRUE,self);
  157.                 if(trace_fraction==1.0 && !(self.enemy.health<1 || !(self.enemy)))
  158.                 {
  159.                         ftemp=vlen(self.enemy.origin-self.origin);
  160.                         if(ftemp>300)
  161.                         {       // far from enemy, approach
  162.                                 vtemp=self.enemy.origin+'0 0 10';
  163.                                 dir=normalize(vtemp-self.origin);
  164.                                 self.velocity=dir*200;
  165.                                 self.angles=vectoangles(self.velocity);
  166.                         }
  167.                         else    // near to enemy, attack
  168.                                 self.owner.wisp_state=WISP_ATTACK;
  169.                 }
  170.                 else    // no valid enemy in sight, go hunt
  171.                         self.owner.wisp_state=WISP_HUNT;
  172.         }
  173.         else    // won't attack the world, go hunt
  174.                 self.owner.wisp_state=WISP_HUNT;
  175. };
  176.  
  177. void () WispHunt =
  178. {
  179.         local float r,mf;
  180.         local float dist=300;
  181.         local float offset;
  182.         local float spd;
  183.         local vector ang,sel;
  184.  
  185.         self.enemy=WispFindTarget();
  186.         if(self.enemy)
  187.         {       // enemy found, approach
  188.                 self.owner.wisp_state=1;
  189.                 return;
  190.         }
  191.         makevectors(self.angles);
  192.         traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  193.         if(trace_fraction<1.0)
  194.         {       // approaching obstacle
  195.                 offset=90-trace_fraction*80;
  196.                 spd=(trace_fraction)*200;       // reduce speed as we get nearer
  197.                 if(trace_fraction*dist<=50)
  198.                 {       // wisp is very near obstacle, panic move (90 degrees)
  199.                         offset=90;
  200.                         sprint(self.owner,"Wisp halted!\n");
  201.                 }
  202.                 mf=0;
  203.                 ang=self.angles;
  204.                 ang_x=anglemod(ang_x+offset);
  205.                 makevectors(ang);
  206.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  207.                 if(trace_fraction>mf)
  208.                 {
  209.                         mf=trace_fraction;
  210.                         sel=ang;
  211.                 }
  212.                 ang=self.angles;
  213.                 ang_x=anglemod(ang_x-offset);
  214.                 makevectors(ang);
  215.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  216.                 if(trace_fraction>mf)
  217.                 {
  218.                         mf=trace_fraction;
  219.                         sel=ang;
  220.                 }
  221.                 ang=self.angles;
  222.                 ang_x=anglemod(ang_x+offset);
  223.                 ang_y=anglemod(ang_y+offset);
  224.                 makevectors(ang);
  225.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  226.                 if(trace_fraction>mf)
  227.                 {
  228.                         mf=trace_fraction;
  229.                         sel=ang;
  230.                 }
  231.                 ang=self.angles;
  232.                 ang_x=anglemod(ang_x+offset);
  233.                 ang_y=anglemod(ang_y-offset);
  234.                 makevectors(ang);
  235.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  236.                 if(trace_fraction>mf)
  237.                 {
  238.                         mf=trace_fraction;
  239.                         sel=ang;
  240.                 }
  241.                 ang=self.angles;
  242.                 ang_y=anglemod(ang_y+offset);
  243.                 makevectors(ang);
  244.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  245.                 if(trace_fraction>mf)
  246.                 {
  247.                         mf=trace_fraction;
  248.                         sel=ang;
  249.                 }
  250.                 ang=self.angles;
  251.                 ang_y=anglemod(ang_y-offset);
  252.                 makevectors(ang);
  253.                         traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  254.                 if(trace_fraction>mf)
  255.                 {
  256.                         mf=trace_fraction;
  257.                         sel=ang;
  258.                 }
  259.                 ang=self.angles;
  260.                 ang_x=anglemod(ang_x-offset);
  261.                 ang_y=anglemod(ang_y+offset);
  262.                 makevectors(ang);
  263.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  264.                 if(trace_fraction>mf)
  265.                 {
  266.                         mf=trace_fraction;
  267.                         sel=ang;
  268.                 }
  269.                 ang=self.angles;
  270.                 ang_x=anglemod(ang_x-offset);
  271.                 ang_y=anglemod(ang_y+offset);
  272.                 makevectors(ang);
  273.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  274.                 if(trace_fraction>mf)
  275.                 {
  276.                         mf=trace_fraction;
  277.                         sel=ang;
  278.                 }
  279.                 ang=self.angles;
  280.                 makevectors(ang);
  281.                 traceline(self.origin,self.origin+v_forward*dist,TRUE,self);
  282.                 if(trace_fraction>mf)
  283.                 {
  284.                         mf=trace_fraction;
  285.                         sel=ang;
  286.                 }
  287.                 self.angles=sel;
  288.                 makevectors(sel);
  289.                 self.velocity=v_forward*spd;
  290.         }
  291.         else
  292.         {       // no obstacle in sight, change course a little, but unpredictably
  293.                 ang=self.angles;
  294.                 r=random()*10 - 5;
  295.                 ang_x=anglemod(ang_x+r);
  296.                 r=random()*10 - 5;
  297.                 ang_y=anglemod(ang_y+r);
  298.                 self.angles=ang;
  299.                 makevectors(ang);
  300.                 self.velocity=v_forward*200;
  301.         }
  302.         self.think=WispThink;
  303.         self.nextthink=time+0.1;
  304. };
  305.  
  306. entity () WispFindTarget =
  307. {       // Find nearest valid target
  308.     local entity head, selected;
  309.     local float dist;
  310.     dist = 100000;
  311.     selected = world;
  312.     head = findradius(self.origin, 100000);
  313.     while(head)
  314.     {
  315.                 if( (head.health > 1) && (head != self) && (head != self.owner) && head.classname != "door" && head.classname != "monster_zombie")
  316.         {
  317.             traceline(self.origin,head.origin,TRUE,self);
  318.             if ( (trace_fraction >= 1) && (vlen(head.origin - self.origin) < dist) )
  319.             {
  320.                 selected = head;
  321.                 dist = vlen(head.origin - self.origin);
  322.             }
  323.         }        
  324.         head = head.chain;
  325.     }
  326.         if (selected != world)
  327.     {
  328.                 sprint (self.owner,"Wisp: attacking ");
  329.         if (selected.classname == "player")
  330.                         sprint (self.owner,selected.netname);
  331.         else
  332.             sprint (self.owner,selected.classname);
  333.         sprint (self.owner,"\n");
  334.     }
  335.     return selected;
  336. };
  337.  
  338. void () WispReset =
  339. {
  340.         self.wisp_state=WISP_HUNT;
  341.         self.wisp.enemy=world;
  342.         self.wisp.angles=self.angles;
  343. };
  344.  
  345. void () WispActivate =
  346. {
  347.         local entity newwisp;
  348.         newwisp=spawn();
  349.         newwisp.solid=SOLID_BBOX;
  350.         newwisp.movetype=MOVETYPE_FLY;
  351.         newwisp.classname="wisp";
  352.         newwisp.owner=self;
  353.  
  354.         self.wisp=newwisp;
  355.         self.wisp_flag=TRUE;
  356.         newwisp.th_pain=Wisp_Pain;
  357.         newwisp.th_die=Wisp_Die;
  358.         newwisp.takedamage=TRUE;
  359.         self.wisp_stuck=FALSE;
  360.         self.wisp_porg='0 0 0';
  361.         self.wisp_view=FALSE;
  362.         WispReset();
  363.         newwisp.health=60;
  364.         newwisp.takedamage=DAMAGE_AIM;
  365.         setmodel(newwisp,"progs/lavaball.mdl");
  366.         setsize(newwisp,'-4 -4 -4','4 4 4');
  367. //        setsize(newwisp,'0 0 0','0 0 0');
  368.         setorigin(newwisp,self.origin+'0 0 16');
  369.  
  370.         spawn_tfog(newwisp.origin);
  371.         sprint(self,"Wisp summoned!\n");
  372.         newwisp.nextthink=time+0.1;
  373.         newwisp.think=WispThink;
  374. };
  375.  
  376. void () WispDeactivate =
  377. {
  378.         if(self.owner.wisp_view==TRUE)
  379.                 WispToggleView();
  380.         spawn_tfog(self.wisp.origin);
  381.         self.wisp.nextthink=time+0.1;
  382.         self.wisp.think=SUB_Remove;
  383.         self.wisp_flag=FALSE;
  384.         sprint(self,"Wisp Banished!\n");
  385. };
  386.  
  387. void () WispToggle =
  388. {
  389.         if(self.wisp_flag)
  390.                 WispDeactivate();
  391.         else
  392.                 WispActivate();
  393. };
  394.  
  395. void (entity tgt) WispFire =
  396. {       // Fire lightning at enemy
  397.         local vector org;
  398.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  399.         org=self.origin;
  400.  
  401.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  402.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  403.     WriteEntity (MSG_BROADCAST, self);
  404.     WriteCoord (MSG_BROADCAST, org_x);
  405.     WriteCoord (MSG_BROADCAST, org_y);
  406.     WriteCoord (MSG_BROADCAST, org_z);
  407.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  408.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  409.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  410.  
  411.         LightningDamage(org,self.enemy.origin,self,5);
  412. };
  413.  
  414. void () WispRecall =
  415. {       // Teleport wisp to self
  416.         if(!self.wisp_flag)
  417.         {
  418.                 sprint(self,"Wisp hasn't been summoned.\n");
  419.                 return;
  420.         }
  421.         spawn_tfog(self.wisp.origin);
  422.         setorigin(self.wisp,self.origin+'0 0 16');
  423.         spawn_tfog(self.wisp.origin);
  424.         self.wisp_stuck=FALSE;
  425.         self.wisp_porg='0 0 0';
  426.         self.wisp.think=WispThink;
  427.         self.wisp.nextthink=time+0.1;
  428.         WispReset();
  429. };
  430.  
  431.