home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1997 January / CD_shareware_1-97.iso / DOS / JUEGOS / QPLUS15.ZIP / COMBAT.QC < prev    next >
Encoding:
Text File  |  1996-09-27  |  6.1 KB  |  287 lines

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