]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/tfcombat.c
Morphed's new Nex model
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / tfcombat.c
1 void () T_MissileTouch;\r
2 void () info_player_start;\r
3 void (entity targ, entity attacker) ClientObituary;\r
4 void (entity Goal, entity AP, float addb) DoResults;\r
5 float (entity Goal, entity AP) Activated;\r
6 float (entity targ, entity attacker, float damage) TeamEqualiseDamage;\r
7 \r
8 // Death MSG Caller\r
9 float deathmsg; // Gonna have to make this work with NexTF's\r
10 \r
11 //compiler-satisfying vars (Add these to defs)\r
12 .void() th_die;                                                                 // Note to self: figure out wtf these 2 do\r
13 .void(entity attacker, float damage) th_pain;   ////\r
14 float skill;    // Skill level. Moot in NexTF (no SP, and bots use some other var)\r
15 .float super_damage_finished; //quad damage over <- convert this to work with nex!\r
16 entity damage_attacker;\r
17 .float immune_to_check;         // as it says\r
18 float rj;       // not sure, really..\r
19 \r
20 \r
21 float is_ally (entity targ, entity attacker) {\r
22         if(targ.team_no == attacker.team_no)\r
23                 return 1;\r
24 \r
25         // civilian class\r
26         //if(targ.class == CLASS_CIVILIAN)\r
27         //      return 2;\r
28 \r
29         return 0;\r
30 }\r
31 \r
32 \r
33 // COMBAT\r
34 void () monster_death_use =\r
35 {\r
36         local entity ent;\r
37         local entity otemp;\r
38         local entity stemp;\r
39 \r
40         if ((self.flags & 1))\r
41         {\r
42                 self.flags = (self.flags - 1);\r
43         }\r
44         if ((self.flags & 2))\r
45         {\r
46                 self.flags = (self.flags - 2);\r
47         }\r
48         if (!self.target)\r
49         {\r
50                 return;\r
51         }\r
52         activator = self.enemy;\r
53         SUB_UseTargets ();\r
54 };\r
55 \r
56 float (entity targ, entity inflictor) CanDamage =\r
57 {\r
58         if ((targ.movetype == 7))\r
59         {\r
60                 traceline (inflictor.origin, (0.5 * (targ.absmin + targ.absmax)), 1, self);\r
61                 if ((trace_fraction == 1))\r
62                 {\r
63                         return (1);\r
64                 }\r
65                 if ((trace_ent == targ))\r
66                 {\r
67                         return (1);\r
68                 }\r
69                 return (0);\r
70         }\r
71         traceline (inflictor.origin, targ.origin, 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         traceline (inflictor.origin, (targ.origin + '15 -15 0'), 1, self);\r
92         if ((trace_fraction == 1))\r
93         {\r
94                 return (1);\r
95         }\r
96         return (0);\r
97 };\r
98 \r
99 void (entity targ, entity attacker) Killed =\r
100 {\r
101         local entity oself;\r
102         local string db;\r
103 \r
104         oself = self;\r
105         self = targ;\r
106         if ((self.health < -99))\r
107         {\r
108                 self.health = -99;\r
109         }\r
110         if (((self.movetype == 7) || (self.movetype == 0)))\r
111         {\r
112                 self.th_die ();\r
113                 self = oself;\r
114                 return;\r
115         }\r
116         if (self.classname == "building_tesla")\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.takedamage)\r
164         {\r
165                 return;\r
166         }\r
167         if ((attacker.classname == "player"))\r
168         {\r
169                 damage = (damage * 0.9);\r
170         }\r
171         if ((attacker.classname == "player"))\r
172         {\r
173                 if ((attacker.super_damage_finished > time))\r
174                 {\r
175                         damage = (damage * 4);\r
176                 }\r
177                 if (((targ.classname != "player") && (targ.classname != "bot") && (targ.classname != "building_tesla")))\r
178                 {\r
179                         if (!Activated (targ, attacker))\r
180                         {\r
181                                 if ((targ.else_goal != 0))\r
182                                 {\r
183                                         te = Findgoal (targ.else_goal);\r
184                                         if (te)\r
185                                         {\r
186                                                 AttemptToActivate (te, attacker, targ);\r
187                                         }\r
188                                 }\r
189                                 return;\r
190                         }\r
191                 }\r
192         }\r
193         damage_attacker = attacker;\r
194         if ((teamplay & (64 | 32)))\r
195         {\r
196                 damage = TeamEqualiseDamage (targ, attacker, damage);\r
197         }\r
198         save = ceil ((targ.armortype * damage));\r
199         if ((save >= targ.armorvalue))\r
200         {\r
201                 save = targ.armorvalue;\r
202                 targ.armortype = 0;\r
203                 targ.armorclass = 0;\r
204                 targ.items = (targ.items - (targ.items & ((8192 | 16384) | 32768)));\r
205         }\r
206 \r
207         targ.armorvalue = (targ.armorvalue - save);\r
208         take = ceil ((damage - save));\r
209         if ((targ.flags & 8))\r
210         {\r
211                 targ.dmg_take = (targ.dmg_take + take);\r
212                 targ.dmg_save = (targ.dmg_save + save);\r
213                 targ.dmg_inflictor = inflictor;\r
214         }\r
215         if (((inflictor != world) && (targ.movetype == 3)))\r
216         {\r
217                 targ.immune_to_check = (time + (damage / 20));\r
218                 dir = (targ.origin - ((inflictor.absmin + inflictor.absmax) * 0.5));\r
219                 dir = normalize (dir);\r
220                 if ((((damage < 60) & ((attacker.classname == "player") & (targ.classname == "player"))) & (attacker.netname != targ.netname)))\r
221                 {\r
222                         targ.velocity = (targ.velocity + ((dir * damage) * 11));\r
223                 }\r
224                 else\r
225                 {\r
226                         targ.velocity = (targ.velocity + ((dir * damage) * 8));\r
227                 }\r
228                 if ((((rj > 1) & ((attacker.classname == "player") & (targ.classname == "player"))) & (attacker.netname == targ.netname)))\r
229                 {\r
230                         targ.velocity = (targ.velocity + ((dir * damage) * rj));\r
231                 }\r
232         }\r
233         if ((targ.flags & 64))\r
234         {\r
235                 return;\r
236         }\r
237         if ((targ.invincible_finished >= time))\r
238         {\r
239                 if ((self.invincible_sound < time))\r
240                 {\r
241                         sound (targ, 3, "items/protect3.wav", 1, 1);\r
242                         self.invincible_sound = (time + 2);\r
243                 }\r
244                 return;\r
245         }\r
246         if (((attacker.classname == "player") && ((targ.classname == "player") || (targ.classname == "building_sentrygun"))))\r
247         {\r
248                 if ((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)))\r
249                 {\r
250                         if ((teamplay & 16))\r
251                         {\r
252                                 return;\r
253                         }\r
254                         else\r
255                         {\r
256                                 if ((teamplay & 8))\r
257                                 {\r
258                                         take = (take / 2);\r
259                                 }\r
260                         }\r
261                 }\r
262         }\r
263 \r
264         //                      MOVED HERE FROM PlayerDamage -- need to port the rest\r
265         // how much damage to deal to armor\r
266         damagearmor = bound(0, damage * 0.2 * (targ.armorvalue / 50) * cvar("g_balance_armor_takedamage"), targ.armorvalue);\r
267         // how much damage armor blocks\r
268         save = bound(0, damage * (targ.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);\r
269         // how much damage to deal to player\r
270         take = bound(0, damage - save, damage);\r
271         targ.armorvalue = targ.armorvalue - damagearmor;\r
272         DelayArmorRegen(targ);\r
273 \r
274         if (((take < 1) && (take != 0)))\r
275         {\r
276                 take = 1;\r
277         }\r
278 \r
279         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
280         {\r
281                 if ((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)))\r
282                 {\r
283                         if ((teamplay & 16))\r
284                         {\r
285                                 return;\r
286                         }\r
287                         else\r
288                         {\r
289                                 if ((teamplay & 8))\r
290                                 {\r
291                                         take = take / 2;\r
292                                 }\r
293                         }\r
294                 }\r
295         }\r
296 \r
297         targ.health = (targ.health - take);\r
298         if ((targ.armorvalue < 1))\r
299         {\r
300                 targ.armorclass = 0;\r
301                 targ.armorvalue = 0;\r
302         }\r
303         if ((targ.health <= 0))\r
304         {\r
305                 Killed (targ, attacker);\r
306                 return;\r
307         }\r
308         oldself = self;\r
309         self = targ;\r
310         if (self.th_pain)\r
311         {\r
312                 self.th_pain (attacker, take);\r
313                 if ((skill >= 3))\r
314                 {\r
315                         self.pain_finished = (time + 5);\r
316                 }\r
317         }\r
318         self = oldself;\r
319 };\r
320 \r
321 void (entity targ, entity inflictor, entity attacker, float damage, float T_flags, float T_AttackType) TF_T_Damage =\r
322 {\r
323         local vector dir;\r
324         local entity oldself;\r
325         local entity te;\r
326         local float save;\r
327         local float take;\r
328         local float olddmsg;\r
329         local float no_damage;\r
330         local float moment;\r
331 \r
332         if (targ.team_no < 1 && targ.classname != "func_button" && targ.classname != "door" && targ.classname != "building_tesla")                      // TEMP\r
333         {                                                               ////\r
334                 return;                                         ////\r
335         }                                                               ////\r
336         if ((targ.takedamage == 0))\r
337         {\r
338                 return;\r
339         }\r
340         if ((T_AttackType & 256))\r
341         {\r
342                 targ.health = damage;\r
343                 return;\r
344         }\r
345         /*if (cease_fire) // this aint needed\r
346         {\r
347                 return;\r
348         }*/\r
349         no_damage = 0;\r
350         if ((attacker.classname == "player"))\r
351         {\r
352                 damage = (damage * 0.9);\r
353                 if ((attacker.super_damage_finished > time))\r
354                 {\r
355                         damage = (damage * 4);\r
356                 }\r
357                 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
358                 {\r
359                         if (!Activated (targ, attacker))\r
360                         {\r
361                                 if ((targ.else_goal != 0))\r
362                                 {\r
363                                         te = Findgoal (targ.else_goal);\r
364                                         if (te)\r
365                                         {\r
366                                                 AttemptToActivate (te, attacker, targ);\r
367                                         }\r
368                                 }\r
369                                 return;\r
370                         }\r
371                 }\r
372         }\r
373         damage_attacker = attacker;\r
374         if ((teamplay & (64 | 32)))\r
375         {\r
376                 damage = TeamEqualiseDamage (targ, attacker, damage);\r
377         }\r
378         if (((targ.armorclass != 0) && (T_AttackType != 0)))\r
379         {\r
380                 if (((targ.armorclass & 1) && (T_AttackType & 1)))\r
381                 {\r
382                         damage = floor ((damage * 0.5));\r
383                 }\r
384                 if (((targ.armorclass & 2) && (T_AttackType & 2)))\r
385                 {\r
386                         damage = floor ((damage * 0.5));\r
387                 }\r
388                 if (((targ.armorclass & 4) && (T_AttackType & 4)))\r
389                 {\r
390                         damage = floor ((damage * 0.5));\r
391                 }\r
392                 if (((targ.armorclass & 8) && (T_AttackType & 8)))\r
393                 {\r
394                         damage = floor ((damage * 0.5));\r
395                 }\r
396                 if (((targ.armorclass & 16) && (T_AttackType & 16)))\r
397                 {\r
398                         damage = floor ((damage * 0.5));\r
399                 }\r
400         }\r
401         if ((T_flags & 1))\r
402         {\r
403                 take = damage;\r
404                 save = 0;\r
405         }\r
406         else\r
407         {\r
408                 save = ceil ((targ.armortype * damage));\r
409                 if ((((((attacker.classname == "player") && (targ.team_no > 0)) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
410                 {\r
411                         if ((T_AttackType & 4))\r
412                         {\r
413                                 if ((teamplay & 1024))\r
414                                 {\r
415                                         save = 0;\r
416                                 }\r
417                                 else\r
418                                 {\r
419                                         if ((teamplay & 512))\r
420                                         {\r
421                                                 save = (save / 2);\r
422                                         }\r
423                                 }\r
424                         }\r
425                         else\r
426                         {\r
427                                 if ((teamplay & 256))\r
428                                 {\r
429                                         save = 0;\r
430                                 }\r
431                                 else\r
432                                 {\r
433                                         if ((teamplay & 128))\r
434                                         {\r
435                                                 save = (save / 2);\r
436                                         }\r
437                                 }\r
438                         }\r
439                 }\r
440                 if ((save >= targ.armorvalue))\r
441                 {\r
442                         save = targ.armorvalue;\r
443                         targ.armortype = 0;\r
444                         targ.armorclass = 0;\r
445                         targ.items = (targ.items - (targ.items & ((8192 | 16384) | 32768)));\r
446                 }\r
447                 targ.armorvalue = (targ.armorvalue - save);\r
448                 take = ceil ((damage - save));\r
449         }\r
450         if ((targ.flags & 8))\r
451         {\r
452                 targ.dmg_take = (targ.dmg_take + take);\r
453                 targ.dmg_save = (targ.dmg_save + save);\r
454                 targ.dmg_inflictor = inflictor;\r
455         }\r
456         if ((((inflictor != world) && (targ.movetype == 3)) && !(targ.tfstate & 65536)))\r
457         {\r
458                 if ((deathmsg != 9))\r
459                 {\r
460                         targ.immune_to_check = (time + (damage / 20));\r
461                         dir = (targ.origin - ((inflictor.absmin + inflictor.absmax) * 0.5));\r
462                         dir = normalize (dir);\r
463                         /*if ((targ.class == 6)) // moot function -- NexTF doesnt have an HWGuy\r
464                         {\r
465                                 moment = (damage / 4);\r
466                                 if ((damage <= 50))\r
467                                 {\r
468                                         moment = 0;\r
469                                 }\r
470                         }\r
471                         else*/\r
472                         {\r
473                                 moment = damage;\r
474                         }\r
475                         if ((((moment < 60) && ((attacker.classname == "player") && (targ.classname == "player"))) && (attacker.netname != targ.netname)))\r
476                         {\r
477                                 targ.velocity = (targ.velocity + ((dir * moment) * 11));\r
478                         }\r
479                         else\r
480                         {\r
481                                 targ.velocity = (targ.velocity + ((dir * moment) * 8));\r
482                         }\r
483                         if ((((rj > 1) && ((attacker.classname == "player") && (targ.classname == "player"))) && (attacker.netname == targ.netname)))\r
484                         {\r
485                                 targ.velocity = (targ.velocity + ((dir * moment) * rj));\r
486                         }\r
487                 }\r
488         }\r
489         if ((targ.flags & 64))\r
490         {\r
491                 return;\r
492         }\r
493         if ((targ.invincible_finished >= time))\r
494         {\r
495                 if ((self.invincible_sound < time))\r
496                 {\r
497                         sound (targ, 3, "items/protect3.wav", 1, 1);\r
498                         self.invincible_sound = (time + 2);\r
499                 }\r
500                 return;\r
501         }\r
502 //      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
503         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
504         {\r
505                 if (((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
506                 {\r
507                         if ((T_AttackType & 4))\r
508                         {\r
509                                 if ((teamplay & 16))\r
510                                 {\r
511                                         no_damage = 1;\r
512                                 }\r
513                                 else\r
514                                 {\r
515                                         if ((teamplay & 8))\r
516                                         {\r
517                                                 take = (take / 2);\r
518                                         }\r
519                                 }\r
520                         }\r
521                         else\r
522                         {\r
523                                 if ((teamplay & 4))\r
524                                 {\r
525                                         no_damage = 1;\r
526                                 }\r
527                                 else\r
528                                 {\r
529                                         if ((teamplay & 2))\r
530                                         {\r
531                                                 take = (take / 2);\r
532                                         }\r
533                                 }\r
534                         }\r
535                 }\r
536         }\r
537         if ((T_flags & 4))\r
538         {\r
539                 if ((targ == attacker))\r
540                 {\r
541                         return;\r
542                 }\r
543         }\r
544 \r
545         local float damagearmor;\r
546         //                      MOVED HERE FROM PlayerDamage -- need to port the rest\r
547         // how much damage to deal to armor\r
548         damagearmor = bound(0, damage * 0.2 * (targ.armorvalue / 50) * cvar("g_balance_armor_takedamage"), targ.armorvalue);\r
549         // how much damage armor blocks\r
550         save = bound(0, damage * (targ.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);\r
551         // how much damage to deal to player\r
552         take = bound(0, damage - save, damage);\r
553         targ.armorvalue = targ.armorvalue - damagearmor;\r
554         DelayArmorRegen(targ);\r
555 \r
556         if ((take < 1))\r
557         {\r
558                 take = 1;\r
559         }\r
560         take = rint (take);\r
561         if ((no_damage == 0))\r
562         {\r
563                 targ.health = (targ.health - take);\r
564         }\r
565         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
566         {\r
567                 if (((((targ.team_no > 0) && (targ.team_no == attacker.team_no)) && (targ != attacker)) && (T_flags & 2)))\r
568                 {\r
569                         olddmsg = deathmsg;\r
570                         if ((T_AttackType & 4))\r
571                         {\r
572                                 deathmsg = 37;\r
573                                 if ((teamplay & 16384))\r
574                                 {\r
575                                         TF_T_Damage (attacker, world, world, take, 1, 0);\r
576                                 }\r
577                                 else\r
578                                 {\r
579                                         if ((teamplay & 8192))\r
580                                         {\r
581                                                 TF_T_Damage (attacker, world, world, (take / 2), 1, 0);\r
582                                         }\r
583                                 }\r
584                         }\r
585                         else\r
586                         {\r
587                                 deathmsg = 37;\r
588                                 if ((teamplay & 4096))\r
589                                 {\r
590                                         TF_T_Damage (attacker, world, world, take, 1, 0);\r
591                                 }\r
592                                 else\r
593                                 {\r
594                                         if ((teamplay & 2048))\r
595                                         {\r
596                                                 TF_T_Damage (attacker, world, world, (take / 2), 1, 0);\r
597                                         }\r
598                                 }\r
599                         }\r
600                         deathmsg = olddmsg;\r
601                 }\r
602         }\r
603         if ((no_damage == 1))\r
604         {\r
605                 return;\r
606         }\r
607         if ((targ.armorvalue < 1))\r
608         {\r
609                 targ.armorclass = 0;\r
610                 targ.armorvalue = 0;\r
611         }\r
612         if ((targ.health <= 0))\r
613         {\r
614                 if ((((inflictor.classname == "detpack") && (inflictor.weaponmode == 1)) && (inflictor.enemy == targ)))\r
615                 {\r
616                         deathmsg = 16;\r
617                 }\r
618                 Killed (targ, attacker);\r
619                 return;\r
620         }\r
621         oldself = self;\r
622         self = targ;\r
623         if (self.th_pain)\r
624         {\r
625                 self.th_pain (attacker, take);\r
626                 if ((skill >= 3))\r
627                 {\r
628                         self.pain_finished = (time + 5);\r
629                 }\r
630         }\r
631         self = oldself;\r
632 };\r
633 \r
634 void (entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =\r
635 {\r
636         local float points;\r
637         local entity head;\r
638         local entity te;\r
639         local vector org;                                                       ////\r
640 \r
641         head = findradius (inflictor.origin, (damage + 40));\r
642         while (head)\r
643         {\r
644                 if ((head != ignore))\r
645                 {\r
646                         if (head.takedamage)\r
647                         {\r
648                                 org = (head.origin + ((head.mins + head.maxs) * 0.5));\r
649                                 points = (0.5 * vlen ((inflictor.origin - org)));\r
650                                 if ((points < 0))\r
651                                 {\r
652                                         points = 0;\r
653                                 }\r
654                                 points = (damage - points);\r
655                                 if ((head == attacker))\r
656                                 {\r
657                                         points = (points * 0.75);\r
658                                 }\r
659                                 if ((points > 0))\r
660                                 {\r
661                                         if (CanDamage (head, inflictor))\r
662                                         {\r
663                                                 if ((head.classname == "monster_shambler"))\r
664                                                 {\r
665                                                         T_Damage (head, inflictor, attacker, (points * 0.5));\r
666                                                 }\r
667                                                 else\r
668                                                 {\r
669                                                         TF_T_Damage (head, inflictor, attacker, points, 2, 4);\r
670                                                 }\r
671                                         }\r
672                                 }\r
673                         }\r
674                 }\r
675                 head = head.chain;\r
676         }\r
677 };\r