]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/tfcombat.c
- Added new backpack/tfitem property -- item_backpack gives metal ammo when var...
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / tfcombat.c
1 void () info_player_start;\r
2 void (entity targ, entity attacker) ClientObituary;\r
3 void (entity Goal, entity AP, float addb) DoResults;\r
4 float (entity Goal, entity AP) Activated;\r
5 float (entity targ, entity attacker, float damage) TeamEqualiseDamage; // TBA Add function for this\r
6 \r
7 // Death MSG Caller\r
8 float deathmsg; // Gonna have to make this work with NexTF's\r
9 \r
10 //compiler-satisfying vars (Add these to defs)\r
11 .void() th_die;                                                                 // The function that gets executed when something "dies"\r
12 .void(entity attacker, float damage) th_pain;   // Function that's executed when an entity gets hit(?)\r
13 float skill;    // Skill level. Moot in NexTF (no SP, and bots use some other var)\r
14 .float super_damage_finished; //quad damage over <- convert this to work with nex!\r
15 entity damage_attacker;\r
16 .float immune_to_check;         // as it says\r
17 float rj;       // not sure, really..\r
18 \r
19 \r
20 float is_ally (entity targ, entity attacker) {\r
21         if(targ.team_no == attacker.team_no)\r
22                 return 1;\r
23 \r
24         // civilian class\r
25         //if(targ.class == CLASS_CIVILIAN)\r
26         //      return 2;\r
27 \r
28         return 0;\r
29 }\r
30 \r
31 \r
32 // COMBAT\r
33 void () monster_death_use =\r
34 {\r
35         if ((self.flags & 1))\r
36         {\r
37                 self.flags = (self.flags - 1);\r
38         }\r
39         if ((self.flags & 2))\r
40         {\r
41                 self.flags = (self.flags - 2);\r
42         }\r
43         if (!self.target)\r
44         {\r
45                 return;\r
46         }\r
47         activator = self.enemy;\r
48         SUB_UseTargets ();\r
49 };\r
50 \r
51 float (entity targ, entity inflictor) CanDamage =\r
52 {\r
53         if ((targ.movetype == 7))\r
54         {\r
55                 traceline (inflictor.origin, (0.5 * (targ.absmin + targ.absmax)), 1, self);\r
56                 if ((trace_fraction == 1))\r
57                 {\r
58                         return (1);\r
59                 }\r
60                 if ((trace_ent == targ))\r
61                 {\r
62                         return (1);\r
63                 }\r
64                 return (0);\r
65         }\r
66         traceline (inflictor.origin, targ.origin, 1, self);\r
67         if ((trace_fraction == 1))\r
68         {\r
69                 return (1);\r
70         }\r
71         traceline (inflictor.origin, (targ.origin + '15 15 0'), 1, self);\r
72         if ((trace_fraction == 1))\r
73         {\r
74                 return (1);\r
75         }\r
76         traceline (inflictor.origin, (targ.origin + '-15 -15 0'), 1, self);\r
77         if ((trace_fraction == 1))\r
78         {\r
79                 return (1);\r
80         }\r
81         traceline (inflictor.origin, (targ.origin + '-15 15 0'), 1, self);\r
82         if ((trace_fraction == 1))\r
83         {\r
84                 return (1);\r
85         }\r
86         traceline (inflictor.origin, (targ.origin + '15 -15 0'), 1, self);\r
87         if ((trace_fraction == 1))\r
88         {\r
89                 return (1);\r
90         }\r
91         return (0);\r
92 };\r
93 \r
94 void (entity targ, entity attacker) Killed =\r
95 {\r
96         local entity oself;\r
97 \r
98         oself = self;\r
99         self = targ;\r
100         if ((self.health < -99))\r
101         {\r
102                 self.health = -99;\r
103         }\r
104         if (((self.movetype == 7) || (self.movetype == 0)))\r
105         {\r
106                 self.th_die ();\r
107                 self = oself;\r
108                 return;\r
109         }\r
110         if (self.classname == "building_tesla")\r
111         {\r
112                 self.th_die ();\r
113                 self = oself;\r
114                 return;\r
115         }\r
116         if (self.th_die && self.classname != "player")          // so objects and buildings use their proper death functions\r
117         {\r
118                 self.th_die ();\r
119                 self = oself;\r
120                 return;\r
121         }\r
122         self.enemy = attacker;\r
123         if ((self.flags & 32))\r
124         {\r
125                 killed_monsters = (killed_monsters + 1);\r
126                 WriteByte (2, 27);\r
127         }\r
128 //      ClientObituary (self, attacker);                // causing crash :/\r
129 //      Obituary (attacker, targ, deathmsg);\r
130         self.takedamage = 0;\r
131         self.touch = SUB_Null;\r
132         monster_death_use ();\r
133 //      self.th_die ();\r
134 // (float unnatural_death, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force\r
135         PlayerKilled (0, targ, attacker, 0, deathmsg);\r
136         self = oself;\r
137 };\r
138 \r
139 void (entity targ, entity inflictor, entity attacker, float damage) T_Damage =\r
140 {\r
141         local vector dir;\r
142         local entity oldself;\r
143         local entity te;\r
144         local float save;\r
145         local float take;\r
146 \r
147         local float damagearmor;\r
148 \r
149         if (targ.team_no < 1 && targ.classname != "func_button" && targ.classname != "door" && targ.classname != "building_tesla")                      // TEMP\r
150         {                                                               ////\r
151                 return;                                         ////\r
152         }                                                               ////\r
153 \r
154         /*if (targ.classname == "building_tesla")\r
155         {\r
156                 targ.health = (targ.health - take);\r
157                 if ((targ.health <= 0))\r
158                 {\r
159                         Killed (targ, attacker);\r
160                 }\r
161                 return;\r
162         }*/\r
163         if (targ.pain_finished < time)          //Don't switch pain sequences like crazy\r
164         {\r
165                 if (random() > 0.5)\r
166                         targ.pain_frame = $pain1;\r
167                 else\r
168                         targ.pain_frame = $pain2;\r
169                 targ.pain_finished = time + 0.5;        //Supajoe\r
170         }\r
171         if(targ.class == CLASS_MEDIC)\r
172         {\r
173                 if(deathmsg == DEATH_BURNING)\r
174                         damage = 0;     // being on fire or near burning targets does nothing to medics\r
175                 // the flame thrower, flame rockets, and hotbombs also do minimal damage\r
176                 else if(deathmsg == WEP_FLAMER ||\r
177                                 deathmsg == WEP_ROCKET_INCENDIARY ||\r
178                                 deathmsg == WEP_HOTBOMBS)\r
179                         damage = damage * cvar("g_balance_class_medic_flame_takedamage");\r
180         }\r
181 \r
182 \r
183         if (!targ.takedamage)\r
184         {\r
185                 return;\r
186         }\r
187         if ((attacker.classname == "player"))\r
188         {\r
189                 damage = (damage * 0.9);\r
190         }\r
191         if ((attacker.classname == "player"))\r
192         {\r
193                 if ((attacker.strength_finished > time))\r
194                 {\r
195                         damage = (damage * 4);\r
196                 }\r
197                 if (((targ.classname != "player") && (targ.classname != "bot") && (targ.classname != "building_tesla")))\r
198                 {\r
199                         if (!Activated (targ, attacker))\r
200                         {\r
201                                 if ((targ.else_goal != 0))\r
202                                 {\r
203                                         te = Findgoal (targ.else_goal);\r
204                                         if (te)\r
205                                         {\r
206                                                 AttemptToActivate (te, attacker, targ);\r
207                                         }\r
208                                 }\r
209                                 return;\r
210                         }\r
211                 }\r
212         }\r
213         damage_attacker = attacker;\r
214         if ((teamplay & (64 | 32)))\r
215         {\r
216                 damage = TeamEqualiseDamage (targ, attacker, damage);\r
217         }\r
218         save = ceil ((targ.armortype * damage));\r
219         if ((save >= targ.armorvalue))\r
220         {\r
221                 save = targ.armorvalue;\r
222                 targ.armortype = 0;\r
223                 targ.armorclass = 0;\r
224                 targ.items = (targ.items - (targ.items & ((8192 | 16384) | 32768)));\r
225         }\r
226 \r
227         targ.armorvalue = (targ.armorvalue - save);\r
228         take = ceil ((damage - save));\r
229         if ((targ.flags & 8))\r
230         {\r
231                 targ.dmg_take = (targ.dmg_take + take);\r
232                 targ.dmg_save = (targ.dmg_save + save);\r
233                 targ.dmg_inflictor = inflictor;\r
234         }\r
235         if (((inflictor != world) && (targ.movetype == 3)))\r
236         {\r
237                 targ.immune_to_check = (time + (damage / 20));\r
238                 dir = (targ.origin - ((inflictor.absmin + inflictor.absmax) * 0.5));\r
239                 dir = normalize (dir);\r
240                 if ((((damage < 60) & ((attacker.classname == "player") & (targ.classname == "player"))) & (attacker.netname != targ.netname)))\r
241                 {\r
242                         targ.velocity = (targ.velocity + ((dir * damage) * 11));\r
243                 }\r
244                 else\r
245                 {\r
246                         targ.velocity = (targ.velocity + ((dir * damage) * 8));\r
247                 }\r
248                 if ((((rj > 1) & ((attacker.classname == "player") & (targ.classname == "player"))) & (attacker.netname == targ.netname)))\r
249                 {\r
250                         targ.velocity = (targ.velocity + ((dir * damage) * rj));\r
251                 }\r
252         }\r
253         if ((targ.flags & 64))\r
254         {\r
255                 return;\r
256         }\r
257         if ((targ.invincible_finished >= time))\r
258         {\r
259                 if ((self.invincible_sound < time))\r
260                 {\r
261                         sound (targ, 3, "items/protect3.wav", 1, 1);\r
262                         self.invincible_sound = (time + 2);\r
263                 }\r
264                 return;\r
265         }\r
266         if (((attacker.classname == "player") && ((targ.classname == "player") || (targ.classname == "building_sentrygun"))))\r
267         {\r
268                 if ((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)))\r
269                 {\r
270                         if ((teamplay & 16))\r
271                         {\r
272                                 return;\r
273                         }\r
274                         else\r
275                         {\r
276                                 if ((teamplay & 8))\r
277                                 {\r
278                                         take = (take / 2);\r
279                                 }\r
280                         }\r
281                 }\r
282         }\r
283 \r
284         //                      MOVED HERE FROM PlayerDamage -- need to port the rest\r
285         // how much damage to deal to armor\r
286         damagearmor = bound(0, damage * 0.2 * (targ.armorvalue / 50) * cvar("g_balance_armor_takedamage"), targ.armorvalue);\r
287         // how much damage armor blocks\r
288         save = bound(0, damage * (targ.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);\r
289         // how much damage to deal to player\r
290         take = bound(0, damage - save, damage);\r
291         targ.armorvalue = targ.armorvalue - damagearmor;\r
292         DelayArmorRegen(targ);\r
293 \r
294         // if being telefragged or killed by a death trigger etc, don't block that\r
295 /*      if(PlayerShouldDie(inflictor, attacker, damage, deathtype))\r
296         {\r
297                 if(take < damage)\r
298                         take = damage; // deal full damage\r
299         }\r
300         else\r
301         {*/\r
302                 // keep the damage the armor allowed through, and further reduce it if the player is using the shield\r
303                 if(targ.class == CLASS_SCOUT)\r
304                         take = SpecialShieldProtect(take);\r
305 //      }\r
306 \r
307         if (((take < 1) && (take != 0)))\r
308         {\r
309                 take = 1;\r
310         }\r
311 \r
312         if (((attacker.classname == "player") && (((((((targ.classname == "player") || (targ.classname == "building_sentrygun")) || (targ.classname == "building_tesla")) || (targ.classname == "building_teleporter")) || (targ.classname == "building_camera")) || (targ.classname == "monster_helo")) || (targ.classname == "laser_drone"))))\r
313         {\r
314                 if ((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)))\r
315                 {\r
316                         if ((teamplay & 16))\r
317                         {\r
318                                 return;\r
319                         }\r
320                         else\r
321                         {\r
322                                 if ((teamplay & 8))\r
323                                 {\r
324                                         take = take / 2;\r
325                                 }\r
326                         }\r
327                 }\r
328         }\r
329 \r
330         targ.health = (targ.health - take);\r
331         if ((targ.armorvalue < 1))\r
332         {\r
333                 targ.armorclass = 0;\r
334                 targ.armorvalue = 0;\r
335         }\r
336         if ((targ.health <= 0))\r
337         {\r
338                 Killed (targ, attacker);\r
339                 return;\r
340         }\r
341         oldself = self;\r
342         self = targ;\r
343         if (self.th_pain)\r
344         {\r
345                 self.th_pain (attacker, take);\r
346                 if ((skill >= 3))\r
347                 {\r
348                         self.pain_finished = (time + 5);\r
349                 }\r
350         }\r
351         self = oldself;\r
352 };\r
353 \r
354 void (entity targ, entity inflictor, entity attacker, float damage, float T_flags, float T_AttackType) TF_T_Damage =\r
355 {\r
356         local vector dir;\r
357         local entity oldself;\r
358         local entity te;\r
359         local float save;\r
360         local float take;\r
361         local float olddmsg;\r
362         local float no_damage;\r
363         local float moment;\r
364 \r
365         if (targ.team_no < 1 && targ.classname != "func_button" && targ.classname != "door" && targ.classname != "building_tesla")                      // TEMP\r
366         {                                                               ////\r
367                 return;                                         ////\r
368         }                                                               ////\r
369         if ((targ.takedamage == 0))\r
370         {\r
371                 return;\r
372         }\r
373         if ((T_AttackType & 256))\r
374         {\r
375                 targ.health = damage;\r
376                 return;\r
377         }\r
378         /*if (cease_fire) // this aint needed\r
379         {\r
380                 return;\r
381         }*/\r
382         no_damage = 0;\r
383         if ((attacker.classname == "player"))\r
384         {\r
385                 damage = (damage * 0.9);\r
386                 if ((attacker.strength_finished > time))\r
387                 {\r
388                         damage = (damage * 4);\r
389                 }\r
390                 if ((((((((((((targ.classname != "player") && (targ.classname != "bot")) && (targ.classname != "building_tesla")) && (targ.classname != "building_sentrygun")) && (targ.classname != "building_dispenser")) && (targ.classname != "trip_bomb")) && (targ.classname != "building_teleporter")) && (targ.classname != "building_camera")) && (targ.classname != "probe")) && (targ.classname != "monster_helo")) && (targ.classname != "laser_drone")))\r
391                 {\r
392                         if (!Activated (targ, attacker))\r
393                         {\r
394                                 if ((targ.else_goal != 0))\r
395                                 {\r
396                                         te = Findgoal (targ.else_goal);\r
397                                         if (te)\r
398                                         {\r
399                                                 AttemptToActivate (te, attacker, targ);\r
400                                         }\r
401                                 }\r
402                                 return;\r
403                         }\r
404                 }\r
405         }\r
406         damage_attacker = attacker;\r
407         if ((teamplay & (64 | 32)))\r
408         {\r
409                 damage = TeamEqualiseDamage (targ, attacker, damage);\r
410         }\r
411         if (((targ.armorclass != 0) && (T_AttackType != 0)))\r
412         {\r
413                 if (((targ.armorclass & 1) && (T_AttackType & 1)))\r
414                 {\r
415                         damage = floor ((damage * 0.5));\r
416                 }\r
417                 if (((targ.armorclass & 2) && (T_AttackType & 2)))\r
418                 {\r
419                         damage = floor ((damage * 0.5));\r
420                 }\r
421                 if (((targ.armorclass & 4) && (T_AttackType & 4)))\r
422                 {\r
423                         damage = floor ((damage * 0.5));\r
424                 }\r
425                 if (((targ.armorclass & 8) && (T_AttackType & 8)))\r
426                 {\r
427                         damage = floor ((damage * 0.5));\r
428                 }\r
429                 if (((targ.armorclass & 16) && (T_AttackType & 16)))\r
430                 {\r
431                         damage = floor ((damage * 0.5));\r
432                 }\r
433         }\r
434         if ((T_flags & 1))\r
435         {\r
436                 take = damage;\r
437                 save = 0;\r
438         }\r
439         else\r
440         {\r
441                 save = ceil ((targ.armortype * damage));\r
442                 if ((((((attacker.classname == "player") && (targ.team_no > 0)) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
443                 {\r
444                         if ((T_AttackType & 4))\r
445                         {\r
446                                 if ((teamplay & 1024))\r
447                                 {\r
448                                         save = 0;\r
449                                 }\r
450                                 else\r
451                                 {\r
452                                         if ((teamplay & 512))\r
453                                         {\r
454                                                 save = (save / 2);\r
455                                         }\r
456                                 }\r
457                         }\r
458                         else\r
459                         {\r
460                                 if ((teamplay & 256))\r
461                                 {\r
462                                         save = 0;\r
463                                 }\r
464                                 else\r
465                                 {\r
466                                         if ((teamplay & 128))\r
467                                         {\r
468                                                 save = (save / 2);\r
469                                         }\r
470                                 }\r
471                         }\r
472                 }\r
473                 if ((save >= targ.armorvalue))\r
474                 {\r
475                         save = targ.armorvalue;\r
476                         targ.armortype = 0;\r
477                         targ.armorclass = 0;\r
478                         targ.items = (targ.items - (targ.items & ((8192 | 16384) | 32768)));\r
479                 }\r
480                 targ.armorvalue = (targ.armorvalue - save);\r
481                 take = ceil ((damage - save));\r
482         }\r
483         if ((targ.flags & 8))\r
484         {\r
485                 targ.dmg_take = (targ.dmg_take + take);\r
486                 targ.dmg_save = (targ.dmg_save + save);\r
487                 targ.dmg_inflictor = inflictor;\r
488         }\r
489         if ((((inflictor != world) && (targ.movetype == 3)) && !(targ.tfstate & 65536)))\r
490         {\r
491                 if ((deathmsg != 9))\r
492                 {\r
493                         targ.immune_to_check = (time + (damage / 20));\r
494                         dir = (targ.origin - ((inflictor.absmin + inflictor.absmax) * 0.5));\r
495                         dir = normalize (dir);\r
496                         /*if ((targ.class == 6)) // moot function -- NexTF doesnt have an HWGuy\r
497                         {\r
498                                 moment = (damage / 4);\r
499                                 if ((damage <= 50))\r
500                                 {\r
501                                         moment = 0;\r
502                                 }\r
503                         }\r
504                         else*/\r
505                         {\r
506                                 moment = damage;\r
507                         }\r
508                         if ((((moment < 60) && ((attacker.classname == "player") && (targ.classname == "player"))) && (attacker.netname != targ.netname)))\r
509                         {\r
510                                 targ.velocity = (targ.velocity + ((dir * moment) * 11));\r
511                         }\r
512                         else\r
513                         {\r
514                                 targ.velocity = (targ.velocity + ((dir * moment) * 8));\r
515                         }\r
516                         if ((((rj > 1) && ((attacker.classname == "player") && (targ.classname == "player"))) && (attacker.netname == targ.netname)))\r
517                         {\r
518                                 targ.velocity = (targ.velocity + ((dir * moment) * rj));\r
519                         }\r
520                 }\r
521         }\r
522         if ((targ.flags & 64))\r
523         {\r
524                 return;\r
525         }\r
526         if ((targ.invincible_finished >= time))\r
527         {\r
528                 if ((self.invincible_sound < time))\r
529                 {\r
530                         sound (targ, 3, "items/protect3.wav", 1, 1);\r
531                         self.invincible_sound = (time + 2);\r
532                 }\r
533                 return;\r
534         }\r
535 //      if (((attacker.classname == "player") && (((((targ.classname == "player") || (targ.classname == "building_sentrygun")) || (targ.classname == "building_dispenser")) || (targ.classname == "building_teleporter_entrance")) || (targ.classname == "building_teleporter_exit"))))\r
536         if (((attacker.classname == "player") && ((((((targ.classname == "player") || (targ.classname == "building_sentrygun")) || (targ.classname == "building_tesla")) || (targ.classname == "building_teleporter")) || (targ.classname == "building_camera")) || (targ.classname == "laser_drone"))))\r
537         {\r
538                 if (((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
539                 {\r
540                         if ((T_AttackType & 4))\r
541                         {\r
542                                 if ((teamplay & 16))\r
543                                 {\r
544                                         no_damage = 1;\r
545                                 }\r
546                                 else\r
547                                 {\r
548                                         if ((teamplay & 8))\r
549                                         {\r
550                                                 take = (take / 2);\r
551                                         }\r
552                                 }\r
553                         }\r
554                         else\r
555                         {\r
556                                 if ((teamplay & 4))\r
557                                 {\r
558                                         no_damage = 1;\r
559                                 }\r
560                                 else\r
561                                 {\r
562                                         if ((teamplay & 2))\r
563                                         {\r
564                                                 take = (take / 2);\r
565                                         }\r
566                                 }\r
567                         }\r
568                 }\r
569         }\r
570         if ((T_flags & 4))\r
571         {\r
572                 if ((targ == attacker))\r
573                 {\r
574                         return;\r
575                 }\r
576         }\r
577 \r
578         local float damagearmor;\r
579         //                      MOVED HERE FROM PlayerDamage -- need to port the rest\r
580         // how much damage to deal to armor\r
581         damagearmor = bound(0, damage * 0.2 * (targ.armorvalue / 50) * cvar("g_balance_armor_takedamage"), targ.armorvalue);\r
582         // how much damage armor blocks\r
583         save = bound(0, damage * (targ.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);\r
584         // how much damage to deal to player\r
585         take = bound(0, damage - save, damage);\r
586         targ.armorvalue = targ.armorvalue - damagearmor;\r
587         DelayArmorRegen(targ);\r
588 \r
589         if ((take < 1))\r
590         {\r
591                 take = 1;\r
592         }\r
593         take = rint (take);\r
594         if ((no_damage == 0))\r
595         {\r
596                 targ.health = (targ.health - take);\r
597         }\r
598         if (((attacker.classname == "player") && (((((targ.classname == "player") || (targ.classname == "building_sentrygun")) || (targ.classname == "building_dispenser")) || (targ.classname == "building_teleporter_entrance")) || (targ.classname == "building_teleporter_exit"))))\r
599         {\r
600                 if (((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
601                 {\r
602                         olddmsg = deathmsg;\r
603                         if ((T_AttackType & 4))\r
604                         {\r
605                                 deathmsg = 37;\r
606                                 if ((teamplay & 16384))\r
607                                 {\r
608                                         TF_T_Damage (attacker, world, world, take, 1, 0);\r
609                                 }\r
610                                 else\r
611                                 {\r
612                                         if ((teamplay & 8192))\r
613                                         {\r
614                                                 TF_T_Damage (attacker, world, world, (take / 2), 1, 0);\r
615                                         }\r
616                                 }\r
617                         }\r
618                         else\r
619                         {\r
620                                 deathmsg = 37;\r
621                                 if ((teamplay & 4096))\r
622                                 {\r
623                                         TF_T_Damage (attacker, world, world, take, 1, 0);\r
624                                 }\r
625                                 else\r
626                                 {\r
627                                         if ((teamplay & 2048))\r
628                                         {\r
629                                                 TF_T_Damage (attacker, world, world, (take / 2), 1, 0);\r
630                                         }\r
631                                 }\r
632                         }\r
633                         deathmsg = olddmsg;\r
634                 }\r
635         }\r
636         if ((no_damage == 1))\r
637         {\r
638                 return;\r
639         }\r
640         if ((targ.armorvalue < 1))\r
641         {\r
642                 targ.armorclass = 0;\r
643                 targ.armorvalue = 0;\r
644         }\r
645         if ((targ.health <= 0))\r
646         {\r
647                 if ((((inflictor.classname == "detpack") && (inflictor.weaponmode == 1)) && (inflictor.enemy == targ)))\r
648                 {\r
649                         deathmsg = 16;\r
650                 }\r
651                 Killed (targ, attacker);\r
652                 return;\r
653         }\r
654         oldself = self;\r
655         self = targ;\r
656         if (self.th_pain)\r
657         {\r
658                 self.th_pain (attacker, take);\r
659                 if ((skill >= 3))\r
660                 {\r
661                         self.pain_finished = (time + 5);\r
662                 }\r
663         }\r
664         self = oldself;\r
665 };\r
666 \r
667 void (entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =\r
668 {\r
669         local float points;\r
670         local entity head;\r
671         local vector org;                                                       ////\r
672 \r
673         head = findradius (inflictor.origin, (damage + 40));\r
674         while (head)\r
675         {\r
676                 if ((head != ignore))\r
677                 {\r
678                         if (head.takedamage)\r
679                         {\r
680                                 org = (head.origin + ((head.mins + head.maxs) * 0.5));\r
681                                 points = (0.5 * vlen ((inflictor.origin - org)));\r
682                                 if ((points < 0))\r
683                                 {\r
684                                         points = 0;\r
685                                 }\r
686                                 points = (damage - points);\r
687                                 if ((head == attacker))\r
688                                 {\r
689                                         points = (points * 0.75);\r
690                                 }\r
691                                 if ((points > 0))\r
692                                 {\r
693                                         if (CanDamage (head, inflictor))\r
694                                         {\r
695                                                 if ((head.classname == "monster_shambler"))\r
696                                                 {\r
697                                                         T_Damage (head, inflictor, attacker, (points * 0.5));\r
698                                                 }\r
699                                                 else\r
700                                                 {\r
701                                                         TF_T_Damage (head, inflictor, attacker, points, 2, 4);\r
702                                                 }\r
703                                         }\r
704                                 }\r
705                         }\r
706                 }\r
707                 head = head.chain;\r
708         }\r
709 };\r