home *** CD-ROM | disk | FTP | other *** search
/ Quake 'em / QUAKEEM.BIN / quake / programs / freak11 / combat.qc < prev    next >
Encoding:
Text File  |  1996-08-16  |  7.0 KB  |  302 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5. void(vector org, vector vel) SpawnMeatSpray;
  6.  
  7. void() monster_death_use;
  8.  
  9. //============================================================================
  10.  
  11. /*
  12. ============
  13. CanDamage
  14.  
  15. Returns true if the inflictor can directly damage the target.  Used for
  16. explosions and melee attacks.
  17. ============
  18. */
  19. float(entity targ, entity inflictor) CanDamage =
  20. {
  21. // bmodels need special checking because their origin is 0,0,0
  22.     if (targ.movetype == MOVETYPE_PUSH)
  23.     {
  24.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  25.         if (trace_fraction == 1)
  26.             return TRUE;
  27.         if (trace_ent == targ)
  28.             return TRUE;
  29.         return FALSE;
  30.     }
  31.     
  32.     traceline(inflictor.origin, targ.origin, TRUE, self);
  33.     if (trace_fraction == 1)
  34.         return TRUE;
  35.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  36.     if (trace_fraction == 1)
  37.         return TRUE;
  38.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  39.     if (trace_fraction == 1)
  40.         return TRUE;
  41.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  42.     if (trace_fraction == 1)
  43.         return TRUE;
  44.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  45.     if (trace_fraction == 1)
  46.         return TRUE;
  47.  
  48.     return FALSE;
  49. };
  50.  
  51.  
  52. /*
  53. ============
  54. Killed
  55. ============
  56. */
  57. void(entity targ, entity attacker) Killed =
  58. {
  59.     local entity oself;
  60.  
  61.     oself = self;
  62.     self = targ;
  63.     
  64.     if (self.health < -99)
  65.         self.health = -99;              // don't let sbar look bad if a player
  66.  
  67.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  68.     {       // doors, triggers, etc
  69.         self.th_die ();
  70.         self = oself;
  71.         return;
  72.     }
  73.  
  74.     self.enemy = attacker;
  75.  
  76. // bump the monster counter
  77.     if (self.flags & FL_MONSTER)
  78.     {
  79.         killed_monsters = killed_monsters + 1;
  80.         WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
  81.     }
  82.  
  83.     ClientObituary(self, attacker);
  84.     
  85.     self.takedamage = DAMAGE_NO;
  86.     self.touch = SUB_Null;
  87.  
  88.     monster_death_use();
  89.     self.th_die ();
  90.     
  91.     self = oself;
  92. };
  93.  
  94.  
  95. /*
  96. ============
  97. T_Damage
  98.  
  99. The damage is coming from inflictor, but get mad at attacker
  100. This should be the only function that ever reduces health.
  101. ============
  102. */
  103. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  104. {
  105.     local   vector  dir;
  106.     local   entity  oldself;
  107.     local   float   save;
  108.     local   float   take;
  109.  
  110.     if (!targ.takedamage)
  111.         return;
  112.  
  113. // used by buttons and triggers to set activator for target firing
  114.     damage_attacker = attacker;
  115.  
  116. // check for quad damage powerup on the attacker
  117.     if (attacker.super_damage_finished > time)
  118.         damage = damage * 4;
  119.  
  120. // save damage based on the target's armor level
  121.  
  122.     save = ceil(targ.armortype*damage);
  123.     if (save >= targ.armorvalue)
  124.     {
  125.         save = targ.armorvalue;
  126.         targ.armortype = 0;     // lost all armor
  127.         targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  128.     }
  129.     
  130.     targ.armorvalue = targ.armorvalue - save;
  131.     take = ceil(damage-save);
  132.  
  133. // add to the damage total for clients, which will be sent as a single
  134. // message at the end of the frame
  135. // FIXME: remove after combining shotgun blasts?
  136.     if (targ.flags & FL_CLIENT)
  137.     {
  138.         targ.dmg_take = targ.dmg_take + take;
  139.         targ.dmg_save = targ.dmg_save + save;
  140.         targ.dmg_inflictor = inflictor;
  141.  
  142.     }
  143.  
  144. // figure momentum add
  145.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  146.     {
  147.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  148.         dir = normalize(dir);
  149.         targ.velocity = targ.velocity + dir*damage*8;
  150.     }
  151.  
  152. // check for godmode or invincibility
  153.     if (targ.flags & FL_GODMODE)
  154.         return;
  155.     if (targ.invincible_finished >= time)
  156.     {
  157.         if (self.invincible_sound < time)
  158.         {
  159.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  160.             self.invincible_sound = time + 2;
  161.         }
  162.         return;
  163.     }
  164.  
  165. // team play damage avoidance
  166.     if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) )
  167.         return;
  168.         
  169. // do the damage
  170. /////////////////////////////////////////////////////Freaked 8/16       
  171.        if (targ.flags & FL_HEMO)   ////////Double Damage for Bleeders!!
  172.     {
  173.     targ.health = targ.health - take;
  174.  
  175.     dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  176.     dir = normalize(dir);
  177.     SpawnMeatSpray (targ.origin, targ.velocity + dir*damage*10);
  178.     sprint (targ, "Your blood flows freely\n");
  179.     stuffcmd (targ, "bf\n");
  180.     
  181.     }
  182. /////////////////////////////////////////////////////Freaked 8/16       
  183.        
  184.        targ.health = targ.health - take;
  185.             
  186.     if (targ.health <= 0)
  187.     {
  188.         Killed (targ, attacker);
  189.         return;
  190.     }
  191.  
  192. // react to the damage
  193.     oldself = self;
  194.     self = targ;
  195.  
  196.     if ( (self.flags & FL_MONSTER) && attacker != world)
  197.     {
  198.     // get mad unless of the same class (except for soldiers)
  199.         if (self != attacker && attacker != self.enemy)
  200.         {
  201.             if ( (self.classname != attacker.classname) 
  202.             || (self.classname == "monster_army" ) )
  203.             {
  204.                 if (self.enemy.classname == "player")
  205.                     self.oldenemy = self.enemy;
  206.                 self.enemy = attacker;
  207.                 FoundTarget ();
  208.             }
  209.         }
  210.     }
  211.  
  212.     if (self.th_pain)
  213.     {
  214.         self.th_pain (attacker, take);
  215.     // nightmare mode monsters don't go into pain frames often
  216.         if (skill == 3)
  217.             self.pain_finished = time + 5;          
  218.     }
  219.  
  220.     self = oldself;
  221. };
  222.  
  223. /*
  224. ============
  225. T_RadiusDamage
  226. ============
  227. */
  228. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  229. {
  230.     local   float   points;
  231.     local   entity  head;
  232.     local   vector  org;
  233.  
  234.     head = findradius(inflictor.origin, damage+40);
  235.     
  236.     while (head)
  237.     {
  238.         if (head != ignore)
  239.         {
  240.             if (head.takedamage)
  241.             {
  242.                 org = head.origin + (head.mins + head.maxs)*0.5;
  243.                 points = 0.5*vlen (inflictor.origin - org);
  244.                 if (points < 0)
  245.                     points = 0;
  246.                 points = damage - points;
  247.                 if (head == attacker)
  248.                     points = points * 0.5;
  249.                 if (points > 0)
  250.                 {
  251.                     if (CanDamage (head, inflictor))
  252.                     {       // shambler takes half damage from all explosions
  253.                         if (head.classname == "monster_shambler")                                               
  254.                             T_Damage (head, inflictor, attacker, points*0.5);
  255.                         else
  256.                             T_Damage (head, inflictor, attacker, points);
  257.                     }
  258.                 }
  259.             }
  260.         }
  261.         head = head.chain;
  262.     }
  263. };
  264.  
  265. /*
  266. ============
  267. T_BeamDamage
  268. ============
  269. */
  270. void(entity attacker, float damage) T_BeamDamage =
  271. {
  272.     local   float   points;
  273.     local   entity  head;
  274.     
  275.     head = findradius(attacker.origin, damage+40);
  276.     
  277.     while (head)
  278.     {
  279.         if (head.takedamage)
  280.         {
  281.             points = 0.5*vlen (attacker.origin - head.origin);
  282.             if (points < 0)
  283.                 points = 0;
  284.             points = damage - points;
  285.             if (head == attacker)
  286.                 points = points * 0.5;
  287.             if (points > 0)
  288.             {
  289.                 if (CanDamage (head, attacker))
  290.                 {
  291.                     if (head.classname == "monster_shambler")                                               
  292.                         T_Damage (head, attacker, attacker, points*0.5);
  293.                     else
  294.                         T_Damage (head, attacker, attacker, points);
  295.                 }
  296.             }
  297.         }
  298.         head = head.chain;
  299.     }
  300. };
  301.  
  302.