home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / patch / mbq073 / iwbotsrc / combat.qc < prev    next >
Encoding:
Text File  |  1996-08-30  |  6.7 KB  |  295 lines

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