]> icculus.org git repositories - divverent/nexuiz.git/blob - attic/TeamNexuiz/game/gamec/w_common.c
now menu qc respects g_campaign_name
[divverent/nexuiz.git] / attic / TeamNexuiz / game / gamec / w_common.c
1 \r
2 // increments sprite frame, loops when end is hit.. simple\r
3 \r
4 float TE_SMOKE =77;\r
5 void (vector vec) WriteVec =\r
6 {\r
7                 WriteCoord (MSG_BROADCAST, vec_x);\r
8                 WriteCoord (MSG_BROADCAST, vec_y);\r
9                 WriteCoord (MSG_BROADCAST, vec_z);\r
10 }\r
11 void (vector org, vector dir, float counts) W_Smoke =\r
12 {\r
13                 WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);\r
14                 WriteByte (MSG_BROADCAST, TE_SMOKE);\r
15                 WriteVec (org);\r
16                 WriteVec (dir);\r
17                 WriteByte (MSG_BROADCAST, counts);\r
18 }\r
19 \r
20 // increments sprite frame, loops when end is hit.. simple\r
21 void animate_sprite (float startframe, float frame_count)\r
22 {\r
23         if ((self.frame - startframe) >= (frame_count - 1 ))\r
24                 self.frame = startframe;\r
25         else\r
26                 self.frame = self.frame + 1;\r
27 }\r
28 \r
29 void W_UpdateAmmo (void)\r
30 {\r
31         /*\r
32         self.items = self.items - (self.items & (IT_NAILS | IT_SHELLS | IT_ROCKETS | IT_CELLS));\r
33 \r
34         if (self.weapon == IT_LASER)\r
35                 self.currentammo = 1;\r
36         else if (self.weapon == IT_SHOTGUN)\r
37         {\r
38                 self.currentammo = self.ammo_shells;\r
39                 self.items = self.items | IT_SHELLS;\r
40         }\r
41         else if (self.weapon == IT_UZI)\r
42         {\r
43                 self.currentammo = self.ammo_nails;\r
44                 self.items = self.items | IT_NAILS;\r
45         }\r
46         else if (self.weapon == IT_GRENADE_LAUNCHER || self.weapon == IT_HAGAR || self.weapon == IT_ROCKET_LAUNCHER)\r
47         {\r
48                 self.currentammo = self.ammo_rockets;\r
49                 self.items = self.items | IT_ROCKETS;\r
50         }\r
51         else if (self.weapon == IT_ELECTRO || self.weapon == IT_NEX || self.weapon == IT_CRYLINK)\r
52         {\r
53                 self.currentammo = self.ammo_cells;\r
54                 self.items = self.items | IT_CELLS;\r
55         }\r
56         */\r
57 }\r
58 \r
59 void W_UpdateWeapon (void)\r
60 {\r
61         /*\r
62         if (self.weapon == IT_LASER)\r
63                 self.weaponmodel = "models/weapons/w_laser.zym";\r
64         else if (self.weapon == IT_SHOTGUN)\r
65                 self.weaponmodel = "models/weapons/w_shotgun.zym";\r
66         else if (self.weapon == IT_UZI)\r
67                 self.weaponmodel = "models/weapons/w_uzi.zym";\r
68         else if (self.weapon == IT_GRENADE_LAUNCHER)\r
69                 self.weaponmodel = "models/weapons/w_gl.zym";\r
70         else if (self.weapon == IT_ELECTRO)\r
71                 self.weaponmodel = "models/weapons/w_electro.zym";\r
72         else if (self.weapon == IT_CRYLINK)\r
73                 self.weaponmodel = "models/weapons/w_crylink.zym";\r
74         else if (self.weapon == IT_NEX)\r
75                 self.weaponmodel = "models/weapons/w_nex.zym";\r
76         else if (self.weapon == IT_HAGAR)\r
77                 self.weaponmodel = "models/weapons/w_hagar.zym";\r
78         else if (self.weapon == IT_ROCKET_LAUNCHER)\r
79                 self.weaponmodel = "models/weapons/w_rl.zym";\r
80         else\r
81                 objerror ("Illegal weapon - please register your guns please!");\r
82         */\r
83 }\r
84 \r
85 float W_GetBestWeapon (entity e)\r
86 {\r
87         /*\r
88         if ((e.items & IT_ROCKET_LAUNCHER) && e.ammo_rockets)\r
89                 return IT_ROCKET_LAUNCHER;\r
90         else if ((e.items & IT_NEX) && e.ammo_cells)\r
91                 return IT_NEX;\r
92         else if ((e.items & IT_HAGAR) && e.ammo_rockets)\r
93                 return IT_HAGAR;\r
94         else if ((e.items & IT_GRENADE_LAUNCHER) && e.ammo_rockets)\r
95                 return IT_GRENADE_LAUNCHER;\r
96         else if ((e.items & IT_ELECTRO) && e.ammo_cells)\r
97                 return IT_ELECTRO;\r
98         else if ((e.items & IT_CRYLINK) && e.ammo_cells)\r
99                 return IT_CRYLINK;\r
100         else if ((e.items & IT_UZI) && e.ammo_nails)\r
101                 return IT_UZI;\r
102         else if ((e.items & IT_SHOTGUN) && e.ammo_shells)\r
103                 return IT_SHOTGUN;\r
104         else\r
105 \r
106                 */\r
107         return IT_LASER;\r
108 }\r
109 \r
110 void ResetExtraWeapon()\r
111 {\r
112         if(self.wpn5 == world)\r
113         {\r
114                 self.wpn5 = spawn();\r
115         }\r
116 \r
117         self.wpn5.weapon = 0;\r
118         self.wpn5.mass = 0;\r
119         self.items = self.items - (self.items & IT_WEP5);\r
120 }\r
121 \r
122 void W_GiveWeapon (entity e, float wep, string name, float wmass)\r
123 {\r
124         entity oldself;\r
125 \r
126         if (!wep)\r
127                 return;\r
128 \r
129         //e.items = e.items | wep;\r
130 \r
131         oldself = self;\r
132         self = e;\r
133 \r
134         self.wpn5.weapon = wep;\r
135         self.wpn5.mass = wmass;\r
136 \r
137         self.items = self.items | IT_WEP5;\r
138 \r
139         weapon_action(self.weapon, WR_UPDATECOUNTS);\r
140         if(self.weapon == WEP5)                                 // if using carrying # 5 already\r
141         {\r
142                 //bprint("reset wep5\n");\r
143                 self.wpn = self.wpn5.weapon;\r
144                 self.switchweapon = WEP5;\r
145                 weapon_action(self.weapon, WR_DROP);\r
146                 self.weapon = 0;\r
147                 //weapon_action(self.wpn, WR_SETUP);    // update the weapon we're holding\r
148                 //weapon_action(self.wpn, WR_RAISE);    // update the weapon we're holding\r
149         }\r
150 \r
151         if (other.classname == "player")\r
152         {\r
153                 sprint (other, "You got the ^2");\r
154                 sprint (other, name);\r
155                 sprint (other, "\n");\r
156         }\r
157 \r
158 \r
159 /*\r
160         W_UpdateWeapon ();\r
161         W_UpdateAmmo ();\r
162 */\r
163         self = oldself;\r
164 }\r
165 \r
166 /*\r
167 void W_SwitchWeapon (float wep)\r
168 {\r
169         float           nextwep;\r
170         var float       noammo = FALSE;\r
171 \r
172         if (wep == 1)\r
173                 nextwep = IT_LASER;\r
174         else if (wep == 2)\r
175         {\r
176                 nextwep = IT_SHOTGUN;\r
177                 if (!self.ammo_shells)\r
178                         noammo = TRUE;\r
179         }\r
180         else if (wep == 3)\r
181         {\r
182                 nextwep = IT_UZI;\r
183                 if (!self.ammo_nails)\r
184                         noammo = TRUE;\r
185         }\r
186         else if (wep == 4)\r
187         {\r
188                 nextwep = IT_CRYLINK;\r
189                 if (!self.ammo_cells)\r
190                         noammo = TRUE;\r
191         }\r
192         else if (wep == 5)\r
193         {\r
194                 nextwep = IT_ELECTRO;\r
195                 if (!self.ammo_cells)\r
196                         noammo = TRUE;\r
197         }\r
198         else if (wep == 6)\r
199         {\r
200                 nextwep = IT_GRENADE_LAUNCHER;\r
201                 if (!self.ammo_rockets)\r
202                         noammo = TRUE;\r
203         }\r
204         else if (wep == 7)\r
205         {\r
206                 nextwep = IT_HAGAR;\r
207                 if (!self.ammo_rockets)\r
208                         noammo = TRUE;\r
209         }\r
210         else if (wep == 8)\r
211         {\r
212                 nextwep = IT_NEX;\r
213                 if (!self.ammo_cells)\r
214                         noammo = TRUE;\r
215         }\r
216         else if (wep == 9)\r
217         {\r
218                 nextwep = IT_ROCKET_LAUNCHER;\r
219                 if (!self.ammo_rockets)\r
220                         noammo = TRUE;\r
221         }\r
222 \r
223 \r
224         if (!(self.items & nextwep))\r
225         {\r
226                 sprint (self, "You don't own that weapon\n");\r
227                 return;\r
228         }\r
229         else if (noammo)\r
230         {\r
231                 sprint (self, "You don't have any ammo for that weapon\n");\r
232                 return;\r
233         }\r
234 \r
235         self.weapon = nextwep;\r
236         W_UpdateWeapon ();\r
237         W_UpdateAmmo ();\r
238         self.attack_finished = time + 0.2;\r
239         if (self.viewzoom != 1)\r
240                 self.viewzoom = 1;\r
241 }\r
242 \r
243 void W_NextWeapon (void)\r
244 {\r
245         float   noammo;\r
246 \r
247         while (TRUE)\r
248         {\r
249                 noammo = FALSE;\r
250 \r
251                 if (self.weapon == IT_ROCKET_LAUNCHER)\r
252                         self.weapon = IT_LASER;\r
253                 else if (self.weapon == IT_LASER)\r
254                 {\r
255                         self.weapon = IT_SHOTGUN;\r
256                         if (!self.ammo_shells)\r
257                                 noammo = TRUE;\r
258                 }\r
259                 else if (self.weapon == IT_SHOTGUN)\r
260                 {\r
261                         self.weapon = IT_UZI;\r
262                         if (!self.ammo_nails)\r
263                                 noammo = TRUE;\r
264                 }\r
265                 else if (self.weapon == IT_UZI)\r
266                 {\r
267                         self.weapon = IT_CRYLINK;\r
268                         if (!self.ammo_cells)\r
269                         noammo = TRUE;\r
270                 }\r
271                 else if (self.weapon == IT_CRYLINK)\r
272                 {\r
273                         self.weapon = IT_ELECTRO;\r
274                         if (!self.ammo_cells)\r
275                                 noammo = TRUE;\r
276                 }\r
277                 else if (self.weapon == IT_ELECTRO)\r
278                 {\r
279                         self.weapon = IT_GRENADE_LAUNCHER;\r
280                         if (!self.ammo_cells)\r
281                                 noammo = TRUE;\r
282                 }\r
283                 else if (self.weapon == IT_GRENADE_LAUNCHER)\r
284                 {\r
285                         self.weapon = IT_HAGAR;\r
286                         if (!self.ammo_rockets)\r
287                                 noammo = TRUE;\r
288                 }\r
289                 else if (self.weapon == IT_HAGAR)\r
290                 {\r
291                         self.weapon = IT_NEX;\r
292                         if (!self.ammo_rockets)\r
293                         noammo = TRUE;\r
294                 }\r
295                 else if (self.weapon == IT_NEX)\r
296                 {\r
297                         self.weapon = IT_ROCKET_LAUNCHER;\r
298                         if (!self.ammo_cells)\r
299                         noammo = TRUE;\r
300                 }\r
301 \r
302                 if ((self.items & self.weapon) && !noammo)\r
303                 {\r
304                         W_UpdateWeapon ();\r
305                         W_UpdateAmmo ();\r
306                         return;\r
307                 }\r
308         }\r
309 }\r
310 \r
311 void W_PreviousWeapon (void)\r
312 {\r
313         float   noammo;\r
314 \r
315         while (TRUE)\r
316         {\r
317                 noammo = FALSE;\r
318 \r
319                 if (self.weapon == IT_SHOTGUN)\r
320                         self.weapon = IT_LASER;\r
321                 else if (self.weapon == IT_UZI)\r
322                 {\r
323                         self.weapon = IT_SHOTGUN;\r
324                         if (!self.ammo_shells)\r
325                                 noammo = TRUE;\r
326                 }\r
327                 else if (self.weapon == IT_CRYLINK)\r
328                 {\r
329                         self.weapon = IT_UZI;\r
330                         if (!self.ammo_nails)\r
331                                 noammo = TRUE;\r
332                 }\r
333                 else if (self.weapon == IT_ELECTRO)\r
334                 {\r
335                         self.weapon = IT_CRYLINK;\r
336                         if (!self.ammo_cells)\r
337                                 noammo = TRUE;\r
338                 }\r
339                 else if (self.weapon == IT_GRENADE_LAUNCHER)\r
340                 {\r
341                         self.weapon = IT_ELECTRO;\r
342                         if (!self.ammo_cells)\r
343                                 noammo = TRUE;\r
344                 }\r
345                 else if (self.weapon == IT_HAGAR)\r
346                 {\r
347                         self.weapon = IT_GRENADE_LAUNCHER;\r
348                         if (!self.ammo_rockets)\r
349                                 noammo = TRUE;\r
350                 }\r
351                 else if (self.weapon == IT_NEX)\r
352                 {\r
353                         self.weapon = IT_HAGAR;\r
354                         if (!self.ammo_rockets)\r
355                                 noammo = TRUE;\r
356                 }\r
357                 else if (self.weapon == IT_ROCKET_LAUNCHER)\r
358                 {\r
359                         self.weapon = IT_NEX;\r
360                         if (!self.ammo_cells)\r
361                                 noammo = TRUE;\r
362                 }\r
363                 else if (self.weapon == IT_LASER)\r
364                 {\r
365                         self.weapon = IT_ROCKET_LAUNCHER;\r
366                         if (!self.ammo_rockets)\r
367                                 noammo = TRUE;\r
368                 }\r
369 \r
370                 if ((self.items & self.weapon) && !noammo)\r
371                 {\r
372                         W_UpdateWeapon ();\r
373                         W_UpdateAmmo ();\r
374                         return;\r
375                 }\r
376         }\r
377 }\r
378 */\r
379 float W_CheckAmmo (void)\r
380 {\r
381         if ((cvar("g_instagib") == 1) | (cvar("g_rocketarena") == 1))\r
382                 return TRUE;\r
383 \r
384         W_UpdateAmmo ();\r
385         if (self.weapon == IT_LASER)\r
386                 return TRUE;\r
387         else if (self.currentammo)\r
388                 return TRUE;\r
389 \r
390         self.weapon = W_GetBestWeapon (self);\r
391         W_UpdateWeapon ();\r
392 \r
393         return FALSE;\r
394 }\r
395 \r
396 /*\r
397 void FireRailgunBullet (vector src, float bdamage, vector dir, float spread, float deathtype)\r
398 {\r
399         vector  v, lastpos;\r
400         entity  saveself, last;\r
401         vector  org;\r
402         org = self.origin + self.view_ofs;\r
403         if (bdamage < 1)\r
404                 return;\r
405 \r
406         last = self;\r
407         lastpos = src;\r
408 \r
409         while (bdamage > 0)\r
410         {\r
411                 traceline_hitcorpse (self, org, org + v_forward * 4096 + v_right * crandom () * spread + v_up * crandom () * spread, FALSE, self);\r
412                 last = trace_ent;\r
413                 lastpos = trace_endpos;\r
414                 if (trace_fraction != 1.0)\r
415                 {\r
416                         if (pointcontents(trace_endpos - dir*4) == CONTENT_SKY)\r
417                                 return;\r
418 \r
419                         if (trace_ent.takedamage || trace_ent.classname == "case")\r
420                         {\r
421                                 if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")\r
422                                         te_blood (trace_endpos, dir * bdamage * 16, bdamage);\r
423                                 Damage (trace_ent, self, self, bdamage, deathtype, trace_endpos, dir * bdamage);\r
424                         }\r
425                 }\r
426                 if (last.solid == SOLID_BSP)\r
427                         bdamage = 0;\r
428         }\r
429 }\r
430 */\r
431 \r
432 void FireRailgunBullet (vector start, vector end, float bdamage, float deathtype)\r
433 {\r
434         local vector hitloc, force;\r
435         local entity ent;\r
436         //local entity explosion;\r
437 \r
438         force = normalize(end - start) * 800; //(bdamage * 10);\r
439 \r
440         // find how far the beam can go until it hits a wall\r
441         traceline (start, end, MOVE_HITMODEL, self);            // doing this enables checking against model\r
442                                                                                                                 // geometry -- leaving it disabled for now since\r
443                                                                                                                 // it's a cpu hog.\r
444         //traceline (start, end, TRUE, self);\r
445         // go a little bit into the wall because we need to hit this wall later\r
446         end = trace_endpos + normalize(end - start);\r
447 \r
448         local float dam_mult;\r
449         local float zdif;\r
450         local float x;\r
451         local vector f;\r
452         local vector g;\r
453         local vector h;\r
454 \r
455         traceline_hitcorpse (self, start, end, FALSE, self);\r
456         if (trace_ent/* && deathtype == WEP_RAILGUN*/)                  // Area damage!\r
457         {\r
458                 if ((trace_ent.classname == "player"))\r
459                 {\r
460                         f = (trace_endpos - start);\r
461                         g_x = trace_endpos_x;\r
462                         g_y = trace_endpos_y;\r
463                         g_z = 0;\r
464                         h_x = trace_ent.origin_x;\r
465                         h_y = trace_ent.origin_y;\r
466                         h_z = 0;\r
467                         x = vlen ((g - h));\r
468                         f = ((normalize (f) * x) + trace_endpos);\r
469                         zdif = (f_z - trace_ent.origin_z);\r
470                         bprint(ftos(zdif));\r
471                         bprint("\n");\r
472                         deathmsg = 18;\r
473                         trace_ent.head_shot_vector = '0 0 0';\r
474                         if (trace_ent.crouch == 1)              // Damage enemy that's crouching\r
475                         {\r
476                                 if (zdif < -5)\r
477                                 {\r
478                                         dam_mult = 0.5;\r
479                                         if ((trace_ent.team_no != self.team_no))\r
480                                         {\r
481                                                 trace_ent.leg_damage = (trace_ent.leg_damage + 1);\r
482                                                 TeamFortress_SetSpeed (trace_ent);\r
483                                                 deathmsg = RAILGUN_LEGSHOT;\r
484                                                 bdamage = bdamage * .8;\r
485                                         }\r
486                                         if ((trace_ent.health > 0))\r
487                                         {\r
488                                                 if ((trace_ent.team_no == self.team_no))\r
489                                                 {\r
490                                                         sprint (self, "Stop shooting team mates!!!\n");\r
491                                                 }\r
492                                                 else\r
493                                                 {\r
494                                                         sprint (trace_ent, "Leg injury!\n");\r
495                                                         sprint (self, "Leg shot - that'll slow him down!\n");\r
496                                                 }\r
497                                         }\r
498                                 }\r
499                                 else\r
500                                 {\r
501                                         if (zdif > 5)\r
502                                         {\r
503                                                 dam_mult = 3;\r
504                                                 stuffcmd (trace_ent, "bf\n");\r
505                                                 //deathmsg = 29;\r
506                                                 if ((trace_ent.health > 0))\r
507                                                 {\r
508                                                         if ((trace_ent.team_no == self.team_no))\r
509                                                         {\r
510                                                                 sprint (self, "Stop shooting team mates!!!\n");\r
511                                                         }\r
512                                                         else\r
513                                                         {\r
514                                                                 trace_ent.head_shot_vector = (trace_ent.origin - self.origin);\r
515                                                                 deathmsg = 29;\r
516                                                                 if (zdif > 9.1)\r
517                                                                 {\r
518                                                                         bdamage = floor(bdamage * 4.0);\r
519                                                                         deathmsg = RAILGUN_HEADSHOT;\r
520                                                                 }\r
521                                                                 else\r
522                                                                 {\r
523                                                                         bdamage = floor(bdamage * 2.5);\r
524                                                                         deathmsg = RAILGUN_CHESTSHOT;\r
525                                                                 }\r
526                                                                 sound (self, 0, "speech/excelent.wav", 1, 0);\r
527                                                         }\r
528                                                 }\r
529                                                 else\r
530                                                 {\r
531                                                         deathmsg = RAILGUN_BODYSHOT;\r
532                                                 }\r
533                                         }\r
534                                 }\r
535                         }\r
536                         else {                                  // Damage standing enemy\r
537                                 if (zdif < 0)\r
538                                 {\r
539                                         dam_mult = 0.5;\r
540                                         if ((trace_ent.team_no != self.team_no))\r
541                                         {\r
542                                                 trace_ent.leg_damage = (trace_ent.leg_damage + 1);\r
543                                                 TeamFortress_SetSpeed (trace_ent);\r
544                                                 deathmsg = RAILGUN_LEGSHOT;\r
545                                                 bdamage = bdamage * .8;\r
546                                                 //T_Damage (trace_ent, self, self, (self.heat * dam_mult));\r
547                                         }\r
548                                         if ((trace_ent.health > 0))\r
549                                         {\r
550                                                 if ((trace_ent.team_no == self.team_no))\r
551                                                 {\r
552                                                         sprint (self, "Stop shooting team mates!!!\n");\r
553                                                 }\r
554                                                 else\r
555                                                 {\r
556                                                         sprint (trace_ent, "Leg injury!\n");\r
557                                                         sprint (self, "Leg shot - that'll slow him down!\n");\r
558                                                         deathmsg = RAILGUN_LEGSHOT;\r
559                                                 }\r
560                                         }\r
561                                         //return;\r
562                                 }\r
563                                 else\r
564                                 {\r
565                                         if (zdif > 20)\r
566                                         {\r
567                                                 dam_mult = 3;\r
568                                                 stuffcmd (trace_ent, "bf\n");\r
569                                                 //deathmsg = 29;\r
570                                                 if ((trace_ent.health > 0))\r
571                                                 {\r
572                                                         if ((trace_ent.team_no == self.team_no))\r
573                                                         {\r
574                                                                 sprint (self, "Stop shooting team mates!!!\n");\r
575                                                         }\r
576                                                         else\r
577                                                         {\r
578                                                                 trace_ent.head_shot_vector = (trace_ent.origin - self.origin);\r
579                                                                 deathmsg = 29;\r
580 //                                                              bdamage = floor(bdamage * 3.5);\r
581                                                                 if (zdif > 31)\r
582                                                                 {\r
583                                                                         bdamage = floor(bdamage * 15.5);\r
584                                                                         deathmsg = RAILGUN_HEADSHOT;\r
585                                                                 }\r
586                                                                 else\r
587                                                                 {\r
588                                                                         bdamage = floor(bdamage * 2.5);\r
589                                                                         deathmsg = RAILGUN_CHESTSHOT;\r
590                                                                 }\r
591 //                                                              T_Damage (trace_ent, self, self, (self.heat * dam_mult));\r
592                                                                 sound (self, 0, "speech/excelent.wav", 1, 0);\r
593 //                                                              if ((trace_ent.health > 0))\r
594 //                                                              {\r
595 //                                                                      sprint (trace_ent, 0, "Head injury!\n");\r
596 //                                                                      sprint (self, 1, "Head shot - that's gotta hurt!\n");\r
597 //                                                              }\r
598                                                         }\r
599                                                         //return;\r
600                                                 }\r
601                                                 else\r
602                                                 {\r
603                                                         deathmsg = RAILGUN_BODYSHOT;\r
604                                                 }\r
605                                         }\r
606                                 }\r
607                         }\r
608                 }\r
609         }\r
610 \r
611         // trace multiple times until we hit a wall, each obstacle will be made\r
612         // non-solid so we can hit the next, while doing this we spawn effects and\r
613         // note down which entities were hit so we can damage them later\r
614         while (1)\r
615         {\r
616                 traceline_hitcorpse (self, start, end, FALSE, self);\r
617 \r
618                 // if it is world we can't hurt it so stop now\r
619                 if (trace_ent == world || trace_fraction == 1)\r
620                         break;\r
621 \r
622                 // make the entity non-solid so we can hit the next one\r
623                 trace_ent.railgunhit = TRUE;\r
624                 trace_ent.railgunhitloc = trace_endpos;\r
625                 trace_ent.railgunhitsolidbackup = trace_ent.solid;\r
626 \r
627                 // stop if this is a wall\r
628                 if (trace_ent.solid == SOLID_BSP)\r
629                         break;\r
630 \r
631                 // make the entity non-solid\r
632                 trace_ent.solid = SOLID_NOT;\r
633         }\r
634 \r
635         // find all the entities the railgun hit and restore their solid state\r
636         ent = findfloat(world, railgunhit, TRUE);\r
637         while (ent)\r
638         {\r
639                 // restore their solid type\r
640                 ent.solid = ent.railgunhitsolidbackup;\r
641                 ent = findfloat(ent, railgunhit, TRUE);\r
642         }\r
643 \r
644         // spawn a temporary explosion entity for RadiusDamage calls\r
645         //explosion = spawn();\r
646 \r
647         // find all the entities the railgun hit and hurt them\r
648         ent = findfloat(world, railgunhit, TRUE);\r
649         while (ent)\r
650         {\r
651                 // get the details we need to call the damage function\r
652                 hitloc = ent.railgunhitloc;\r
653                 ent.railgunhitloc = '0 0 0';\r
654                 ent.railgunhitsolidbackup = SOLID_NOT;\r
655                 ent.railgunhit = FALSE;\r
656 \r
657                 // apply the damage\r
658                 if (ent.takedamage || ent.classname == "case")\r
659 //                      Damage (ent, self, self, bdamage, deathtype, hitloc, force);\r
660                         Damage (ent, self, self, bdamage, deathmsg, hitloc, force);\r
661 \r
662                 // create a small explosion to throw gibs around (if applicable)\r
663                 //setorigin (explosion, hitloc);\r
664                 //RadiusDamage (explosion, self, 10, 0, 50, world, 300, deathtype);\r
665 \r
666                 // advance to the next entity\r
667                 ent = findfloat(ent, railgunhit, TRUE);\r
668         }\r
669 \r
670         // we're done with the explosion entity, remove it\r
671         //remove(explosion);\r
672 }\r
673 \r
674 // Area damage function --\r
675 //      added this so I dont have to paste this into every function I want area damage in.\r
676 //      Returns a value of LEGSHOT, BODYSHOT, CHESTSHOT, or HEADSHOT.\r
677 float (entity a, vector start, vector end, float flt, entity b) FindBodyDamage =\r
678 {\r
679         local float dam_mult;\r
680         local float zdif;\r
681         local float x;\r
682         local vector f;\r
683         local vector g;\r
684         local vector h;\r
685 \r
686         traceline_hitcorpse (a, start, end, flt, b);\r
687         if (trace_ent)\r
688         {\r
689                 if ((trace_ent.classname == "player"))\r
690                 {\r
691                         f = (trace_endpos - start);\r
692                         g_x = trace_endpos_x;\r
693                         g_y = trace_endpos_y;\r
694                         g_z = 0;\r
695                         h_x = trace_ent.origin_x;\r
696                         h_y = trace_ent.origin_y;\r
697                         h_z = 0;\r
698                         x = vlen ((g - h));\r
699                         f = ((normalize (f) * x) + trace_endpos);\r
700                         zdif = (f_z - trace_ent.origin_z);\r
701                         bprint(ftos(x));\r
702                         bprint("\n");\r
703                         deathmsg = 18;\r
704                         trace_ent.head_shot_vector = '0 0 0';\r
705                         if (trace_ent.crouch == 1)              // Damage enemy that's crouching\r
706                         {\r
707                                 if (zdif < -5)\r
708                                 {\r
709                                         dam_mult = 0.5;\r
710                                         if ((trace_ent.team_no != self.team_no))\r
711                                         {\r
712                                                 trace_ent.leg_damage = (trace_ent.leg_damage + 1);\r
713 //                                              TeamFortress_SetSpeed (trace_ent);\r
714                                                 return LEGSHOT;\r
715                                         }\r
716 /*                                      if ((trace_ent.health > 0))\r
717                                         {\r
718                                                 if ((trace_ent.team_no == self.team_no))\r
719                                                 {\r
720                                                         sprint (self, "Stop shooting team mates!!!\n");\r
721                                                 }\r
722                                                 else\r
723                                                 {\r
724                                                         sprint (trace_ent, "Leg injury!\n");\r
725                                                         sprint (self, "Leg shot - that'll slow him down!\n");\r
726                                                 }\r
727                                         }*/\r
728                                 }\r
729                                 else\r
730                                 {\r
731                                         if (zdif > 5)\r
732                                         {\r
733                                                 dam_mult = 3;\r
734                                                 stuffcmd (trace_ent, "bf\n");\r
735                                                 if ((trace_ent.health > 0))\r
736                                                 {\r
737                                                         /*if ((trace_ent.team_no == self.team_no))\r
738                                                         {\r
739                                                                 sprint (self, "Stop shooting team mates!!!\n");\r
740                                                         }\r
741                                                         else*/\r
742                                                         {\r
743                                                                 trace_ent.head_shot_vector = (trace_ent.origin - self.origin);\r
744                                                                 deathmsg = 29;\r
745                                                                 if (zdif > 9.1)\r
746                                                                 {\r
747                                                                         return HEADSHOT;\r
748                                                                 }\r
749                                                                 else\r
750                                                                 {\r
751                                                                         return CHESTSHOT;\r
752                                                                 }\r
753                                                         }\r
754                                                 }\r
755                                                 else\r
756                                                 {\r
757                                                         return BODYSHOT;\r
758                                                 }\r
759                                         }\r
760                                 }\r
761                         }\r
762                         else {                                  // Damage standing enemy\r
763 //                              if (zdif < 0)\r
764                                 if (zdif < 3)\r
765                                 {\r
766                                         dam_mult = 0.5;\r
767                                         if ((trace_ent.team_no != self.team_no))\r
768                                         {\r
769                                                 //trace_ent.leg_damage = (trace_ent.leg_damage + 1); // no leg dmg?\r
770 //                                              TeamFortress_SetSpeed (trace_ent);\r
771                                                 return LEGSHOT;\r
772                                         }\r
773 /*                                      if ((trace_ent.health > 0))\r
774                                         {\r
775                                                 if ((trace_ent.team_no == self.team_no))\r
776                                                 {\r
777                                                         sprint (self, "Stop shooting team mates!!!\n");\r
778                                                 }\r
779                                                 else\r
780                                                 {\r
781                                                         sprint (trace_ent, "Leg injury!\n");\r
782                                                         sprint (self, "Leg shot - that'll slow him down!\n");\r
783                                                 }\r
784                                         }*/\r
785                                 }\r
786                                 else\r
787                                 {\r
788                                         if (zdif > 20)\r
789                                         {\r
790                                                 dam_mult = 3;\r
791                                                 stuffcmd (trace_ent, "bf\n");\r
792                                                 if ((trace_ent.health > 0))\r
793                                                 {\r
794                                                         /*if ((trace_ent.team_no == self.team_no))\r
795                                                         {\r
796                                                                 sprint (self, "Stop shooting team mates!!!\n");\r
797                                                         }\r
798                                                         else*/\r
799                                                         {\r
800                                                                 trace_ent.head_shot_vector = (trace_ent.origin - self.origin);\r
801                                                                 if (zdif > 31)\r
802                                                                 {\r
803                                                                         return HEADSHOT;\r
804                                                                 }\r
805                                                                 else\r
806                                                                 {\r
807                                                                         return CHESTSHOT;\r
808                                                                 }\r
809                                                         }\r
810                                                 }\r
811                                                 else\r
812                                                 {\r
813                                                         return BODYSHOT;\r
814                                                 }\r
815                                         }\r
816                                 }\r
817                         }\r
818                 }\r
819         }\r
820 };\r
821 \r
822 void fireBullet2 (vector start, vector dir, float spread, float damage, float dtype, float tracer, float force)\r
823 {\r
824         vector  end;\r
825         float r;\r
826         local entity e;\r
827         local float bdamage;\r
828 \r
829         // use traceline_hitcorpse to make sure it can hit gibs and corpses too\r
830         dir = dir + randomvec() * spread;\r
831         end = start + dir * 4096;\r
832         traceline_hitcorpse (self, start, end, FALSE, self);\r
833 \r
834         if (dtype == WEP_PISTOL)                        // if pistol weapon, apply area damage\r
835         {\r
836                 bdamage = FindBodyDamage (self, start, end, FALSE, self);\r
837                 if (bdamage == HEADSHOT)\r
838                 {\r
839                         damage = damage * 2.5;\r
840                         dtype = PISTOL_HEADSHOT;\r
841                 }\r
842                 else if (bdamage == LEGSHOT)\r
843                 {\r
844                         damage = damage * .75;\r
845                         dtype = PISTOL_LEGSHOT;\r
846                 }\r
847                 else\r
848                 {\r
849                         dtype = PISTOL_BODYSHOT;\r
850                 }\r
851         }\r
852 \r
853         if (tracer)\r
854         {\r
855                 e = spawn();\r
856                 e.owner = self;\r
857                 e.movetype = MOVETYPE_FLY;\r
858                 e.solid = SOLID_NOT;\r
859                 e.think = SUB_Remove;\r
860                 e.nextthink = time + vlen(trace_endpos - start) / 6000;\r
861                 if (dtype == WEP_PISTOL)                        // if pistol, show slower bullet\r
862                         e.velocity = dir * 1750;\r
863                 else\r
864                         e.velocity = dir * 6000;\r
865                 e.angles = vectoangles(e.velocity);\r
866                 setmodel (e, "models/tracer.mdl");\r
867                 setsize (e, '0 0 0', '0 0 0');\r
868                 setorigin (e, start);\r
869                 e.effects = e.effects | EF_ADDITIVE;\r
870         }\r
871 \r
872         // FIXME - causes excessive 'tinking'. Hopefully remove "tink1.wav" from the ricochets with csqc\r
873         if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY))\r
874         {\r
875                 if (trace_ent.solid == SOLID_BSP)\r
876                 {\r
877                         pointcontents (self.origin);\r
878                         te_gunshot (trace_endpos);\r
879                         r = random ();\r
880                         if (r < 0.10)\r
881                                 PointSound (trace_endpos, "weapons/ric1.wav", 1, ATTN_NORM);\r
882                         else if (r < 0.20)\r
883                                 PointSound (trace_endpos, "weapons/ric2.wav", 1, ATTN_NORM);\r
884                         else if (r < 0.30)\r
885                                 PointSound (trace_endpos, "weapons/ric3.wav", 1, ATTN_NORM);\r
886                 }\r
887                 else if (trace_ent.classname == "player" || trace_ent.classname == "corpse" || trace_ent.classname == "gib")\r
888                         sound (self, CHAN_BODY, "misc/hit.wav", 1, ATTN_NORM);\r
889                 Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * force);\r
890         }\r
891 }\r
892 \r
893 void fireBullet (vector start, vector dir, float spread, float damage, float dtype, float tracer)\r
894 {\r
895         fireBullet2(start, dir, spread, damage, dtype, tracer, damage * 5); // default force value\r
896 }\r
897 \r
898 /*\r
899 void W_Attack (void)\r
900 {\r
901         if (self.deadflag != DEAD_NO)\r
902         {\r
903                 if (self.death_time < time)\r
904                         PutClientInServer();\r
905 \r
906                 return;\r
907         }\r
908 \r
909         if (!W_CheckAmmo ())\r
910                 return;\r
911 \r
912         makevectors (self.v_angle);\r
913         //if (self.weapon == IT_LASER)\r
914         //      W_Laser_Attack ();\r
915         //if (self.weapon == IT_SHOTGUN)\r
916                 //W_Shotgun_Attack ();\r
917         //else if (self.weapon == IT_UZI)\r
918                 //W_Uzi_Attack ();\r
919         if (self.weapon == IT_CRYLINK)\r
920                 W_Crylink_Attack ();\r
921         else if (self.weapon == IT_ELECTRO)\r
922                 {\r
923                 W_Electro_Attack (self.electrocount);\r
924                 self.electrocount = self.electrocount + 1;\r
925                 if (self.electrocount == 3)\r
926                         self.electrocount = 0;\r
927                 }\r
928         else if (self.weapon == IT_GRENADE_LAUNCHER)\r
929                 W_Grenade_Attack ();\r
930         else if (self.weapon == IT_HAGAR)\r
931                 W_Hagar_Attack ();\r
932         else if (self.weapon == IT_NEX)\r
933                 W_Nex_Attack ();\r
934         //else if (self.weapon == IT_ROCKET_LAUNCHER)\r
935         //      W_Rocket_Attack ();\r
936 \r
937         W_UpdateAmmo ();\r
938 }\r
939 \r
940 void W_SecondaryAttack (void)\r
941 {\r
942         if (self.deadflag != DEAD_NO)\r
943         {\r
944                 if (self.death_time < time)\r
945                         PutClientInServer();\r
946 \r
947                 return;\r
948         }\r
949 \r
950         if (!W_CheckAmmo ())\r
951                 return;\r
952 \r
953         makevectors (self.v_angle);\r
954         //if (self.weapon == IT_LASER)\r
955                 //W_Laser_Attack2 ();\r
956         //if (self.weapon == IT_SHOTGUN)\r
957                 //W_Shotgun_Attack2 ();\r
958         //else if (self.weapon == IT_UZI)\r
959                 //W_Uzi_Attack2 ();\r
960         else if (self.weapon == IT_CRYLINK)\r
961                 W_Crylink_Attack2 ();\r
962         else if (self.weapon == IT_ELECTRO) {\r
963                 W_Electro_Attack2 (self.electrocount);\r
964                 self.electrocount = self.electrocount + 1;\r
965                 if (self.electrocount == 3)\r
966                         self.electrocount = 0;\r
967                 }\r
968         else if (self.weapon == IT_GRENADE_LAUNCHER)\r
969                 W_Grenade_Attack2 ();\r
970         else if (self.weapon == IT_HAGAR)\r
971                 W_Hagar_Attack2 ();\r
972         else if (self.weapon == IT_NEX)\r
973                 W_Nex_Attack2 ();\r
974         //else if (self.weapon == IT_ROCKET_LAUNCHER)\r
975                 //W_Rocket_Attack2 ();\r
976 \r
977         W_UpdateAmmo ();\r
978 }\r
979 \r
980 void W_ThirdAttack (void)\r
981 {\r
982         if (self.deadflag != DEAD_NO)\r
983         {\r
984                 if (self.death_time < time)\r
985                         PutClientInServer();\r
986 \r
987                 return;\r
988         }\r
989 \r
990         if (!W_CheckAmmo ())\r
991                 return;\r
992 \r
993         makevectors (self.v_angle);\r
994         //if (self.weapon == IT_LASER)\r
995                 //W_Laser_Attack2 ();\r
996         //if (self.weapon == IT_SHOTGUN)\r
997                 //W_Shotgun_Attack2 ();\r
998         //else if (self.weapon == IT_UZI)\r
999                 //W_Uzi_Attack3 ();\r
1000         else if (self.weapon == IT_CRYLINK)\r
1001                 W_Crylink_Attack2 ();\r
1002         else if (self.weapon == IT_ELECTRO) {\r
1003                 W_Electro_Attack3 (self.electrocount);\r
1004                 self.electrocount = self.electrocount + 1;\r
1005                 if (self.electrocount == 3)\r
1006                         self.electrocount = 0;\r
1007                 }\r
1008         else if (self.weapon == IT_GRENADE_LAUNCHER)\r
1009                 W_Grenade_Attack3 ();\r
1010         else if (self.weapon == IT_HAGAR)\r
1011                 W_Hagar_Attack3 ();\r
1012         else if (self.weapon == IT_NEX)\r
1013                 W_Nex_Attack2 ();\r
1014         //else if (self.weapon == IT_ROCKET_LAUNCHER)\r
1015                 //W_Rocket_Attack3 ();\r
1016 \r
1017         W_UpdateAmmo ();\r
1018 }\r
1019 */\r
1020 \r
1021 float RateFlameDamage(float flametime, float flamedmg, float flamerate)\r
1022 {\r
1023         // return (how much longer flame will last) * (how much to damage per think / how often to think)\r
1024         return (flametime - time) * (flamedmg / flamerate);\r
1025 }\r
1026 \r
1027 /*void FlamePuffThink()\r
1028 {\r
1029         self.nextthink = time + self.cnt;\r
1030         self.frame = self.frame + 1;\r
1031         if(self.frame >= self.count)\r
1032                 self.think = SUB_Remove;\r
1033 }\r
1034 */\r
1035 void FlameBurnTarget();\r
1036 \r
1037 \r
1038 entity CreateFlame(entity targ, entity attacker)\r
1039 {\r
1040         entity f;\r
1041         f = targ.onfire = spawn();\r
1042         f.classname = "burning";\r
1043         f.owner = attacker;\r
1044         f.enemy = targ;\r
1045         f.dmg = 0;\r
1046         f.ltime = 0;\r
1047         f.wait = 0;\r
1048         f.think = FlameBurnTarget;\r
1049         f.onfire = spawn();\r
1050 \r
1051         f.effects = f.onfire.effects = EF_ADDITIVE;\r
1052         f.scale = f.onfire.scale = 2;\r
1053 \r
1054         setmodel(f, "models/sprites/fire_top.spr32");\r
1055         setattachment(f, f.enemy, "");\r
1056         setmodel(f.onfire, "models/sprites/fire_base.spr32");\r
1057 \r
1058         setorigin(f.onfire, '0 0 -5' * f.scale);\r
1059         setorigin(f, '0 0 2' * f.scale + '0 0 20');\r
1060         setattachment(f.onfire, f, "");\r
1061 \r
1062         return f;\r
1063 }\r
1064 \r
1065 entity IgniteTarget (entity targ, entity attacker, float flametime, float flamedmg, float flamerate, float rateflame)\r
1066 {\r
1067         entity f;\r
1068 \r
1069         //bprint("ignite targets?\n");\r
1070 \r
1071         if(targ.class == CLASS_PYRO)\r
1072         {\r
1073                 //flametime = flametime / 5; // pyros don't stay on fire for long\r
1074                 return world; // don't set pyros on fire\r
1075         }\r
1076 \r
1077         if(targ.class == CLASS_MEDIC)\r
1078         {\r
1079                 //flametime = flametime / 3; // medics don't stay on fire for long\r
1080                 return world; // don't set medics on fire\r
1081         }\r
1082 \r
1083         f = targ.onfire;\r
1084         if(f == world)\r
1085         {\r
1086                 f = CreateFlame(targ, attacker);\r
1087         }\r
1088         else\r
1089         {\r
1090                 if(f.nextthink <= 0)\r
1091                         f.nextthink = time + flamerate;\r
1092         }\r
1093 \r
1094 \r
1095 //      bprint(ftos(f.wait), ", ", ftos(f.dmg), ", ", ftos(f.ltime), "\n");\r
1096         //bprint(ftos(flametime), ", ", ftos(flamedmg), ", ", ftos(flamerate), "\n");\r
1097 //      bprint(ftos(RateFlameDamage(f.wait, f.dmg, f.ltime)), ", ", ftos(RateFlameDamage(flametime, flamedmg, flamerate)), "\n");\r
1098 \r
1099         if(rateflame && RateFlameDamage(f.wait, f.dmg, f.ltime) > RateFlameDamage(time + flametime, flamedmg, flamerate))\r
1100         {\r
1101                 f.owner = attacker; // give the new attacker ownership of the burn damage\r
1102                 return f; // current damage rating is larger, don't replace it\r
1103         }\r
1104 \r
1105         //bprint("burning success: ", ftos(flametime), "\n");\r
1106 \r
1107         f.dmg = flamedmg;\r
1108         f.ltime = flamerate;\r
1109         f.wait = time + flametime;\r
1110 \r
1111         if(!f.nextthink || f.nextthink > time + f.ltime)\r
1112                 f.nextthink = time + f.ltime;\r
1113 \r
1114         return f;\r
1115 }\r
1116 \r
1117 void ExtinguishFlame(entity targ)\r
1118 {\r
1119         entity f, b;\r
1120         if(!targ.onfire)//targ.onfire.classname != "burning")\r
1121                 return;\r
1122         //bprint(strcat("ExtinguishFlame(", targ.classname, ") ", targ.onfire.classname, "\n"));\r
1123 \r
1124         f = targ.onfire;\r
1125         b = targ.onfire.onfire;\r
1126 \r
1127         // fixme: hiss sound\r
1128 \r
1129         if(b)\r
1130         {\r
1131                 b.think = SUB_Null;\r
1132                 b.nextthink = -1;\r
1133                 setmodel(b, "models/sprites/null.spr");\r
1134                 setattachment(b, world, "");\r
1135                 remove(b); // remove base model\r
1136                 //targ.onfire.onfire.think = SUB_Remove;\r
1137                 //targ.onfire.onfire.nextthink = time + 0.1;\r
1138                 f.onfire = world;\r
1139         }\r
1140         f.think = SUB_Null;\r
1141         f.nextthink = -1;\r
1142         setmodel(f, "models/sprites/null.spr");\r
1143         setattachment(f, world, "");\r
1144         //targ.onfire.think = SUB_Remove;\r
1145         //targ.onfire.nextthink = time + 0.1;\r
1146         remove(f);\r
1147         targ.onfire = world;\r
1148 }\r
1149 \r
1150 void FlameBurnTarget()\r
1151 {\r
1152         entity head;\r
1153         float flametime, flametimemax, radius, flameratio, distratio, edgeratio, damage;\r
1154         //bprint("flame burn target\n");\r
1155 \r
1156         if(self.enemy == world || self.enemy.classname == "gib")\r
1157         {\r
1158                 if(self.enemy != world)\r
1159                 {\r
1160                         //bprint("on a gib, remove flame\n");\r
1161                         //self.enemy.onfire = world;\r
1162                         ExtinguishFlame(self.enemy);\r
1163                         return;\r
1164                 }\r
1165                 //bprint("enemy is world, remove flame\n");\r
1166                 self.think = SUB_Null;\r
1167                 self.nextthink = -1;\r
1168                 setmodel(self, "models/sprites/null.spr");\r
1169                 setattachment(self, world, "");\r
1170                 if(self.onfire)\r
1171                 {\r
1172                         self.onfire.think = SUB_Null;\r
1173                         self.onfire.nextthink = -1;\r
1174                         setmodel(self.onfire, "models/sprites/null.spr");\r
1175                         setattachment(self.onfire, world, "");\r
1176                         remove(self.onfire);\r
1177                         self.onfire = world;\r
1178                 }\r
1179                 remove(self);\r
1180                 return;\r
1181         }\r
1182 \r
1183         if(self.wait < time || self.enemy.waterlevel > 2 || (!self.enemy.takedamage && self.enemy.classname != "grenade"))\r
1184         {\r
1185                 /*if(self.enemy != world)\r
1186                 {\r
1187                         self.enemy.effects = self.enemy.effects - (self.enemy.effects & EF_FLAME);\r
1188                         self.enemy.onfire = world;\r
1189                 }\r
1190                 remove(self);*/\r
1191                 ExtinguishFlame(self.enemy);\r
1192                 return;\r
1193         }\r
1194         self.nextthink = time + self.ltime;\r
1195 \r
1196         Damage (self.enemy, self, self.owner, self.dmg, DEATH_BURNING, self.enemy.origin - '0 0 5', '0 0 0');//'0 0 -1' * self.dmg);\r
1197 \r
1198         // flames spread to other targets\r
1199 \r
1200         radius = cvar("g_balance_heat_radius");\r
1201         head = findradius(self.enemy.origin, radius);\r
1202         while(head)\r
1203         {\r
1204                 if((head.takedamage || head.classname == "grenade") && head != self.enemy)\r
1205                 {\r
1206                         //bprint(strcat("maybe burn ", head.classname, "\n"));\r
1207                         // don't harm or spread to allies or pyros\r
1208                         //if(!(head.classname == "player" && (head.team == self.owner.team || head.class == CLASS_PYRO)) )\r
1209                         if(head.classname == "player")\r
1210                         {\r
1211                                 if(head.class == CLASS_PYRO || head.class == CLASS_MEDIC) // pyros & medics are mostly immune to fire\r
1212                                 {       head = head.chain;      continue;}\r
1213                                 if(head.team == self.owner.team && teamplay) // don't hurt teammates\r
1214                                 {       head = head.chain;      continue;}\r
1215                         }\r
1216 \r
1217                         traceline(self.enemy.origin, head.origin, TRUE, self);\r
1218                         if(trace_fraction >= 1)\r
1219                         {\r
1220                                 //bprint(strcat("burn ", head.classname, "\n"));\r
1221                                 edgeratio = cvar("g_balance_heat_edgeratio");\r
1222                                 distratio = ( 1 - (vlen(self.enemy.origin - head.origin) / radius) );\r
1223                                 flameratio = edgeratio + distratio*(1 - edgeratio);\r
1224 \r
1225                                 // increase the player's heat; if it goes over the max it'll get capped automatically by the cooldown code\r
1226                                 //head.flame_heat = cvar("g_balance_maxheat");\r
1227                                 head.flame_heat = head.flame_heat + flameratio * cvar("g_balance_heatup_rate") * self.ltime;\r
1228                                 //head.flame_heat_time = time;\r
1229 \r
1230                                 // deal direct damage from the heat radiated by the fire\r
1231                                 damage = flameratio * self.dmg*cvar("g_balance_heat_damage");\r
1232                                 Damage (head, self, self.owner, damage, DEATH_BURNING, self.enemy.origin, '0 0 0');\r
1233 \r
1234                                 if(head.flame_heat >= 1.0 && head.takedamage == DAMAGE_AIM && head.health > 0)\r
1235                                 {\r
1236                                         flametimemax = cvar("g_balance_heat_timemax");\r
1237                                         flametime = (self.wait - time) * cvar("g_balance_heat_transfer");\r
1238                                         if(flametime > flametimemax)\r
1239                                                 flametime = flametimemax;\r
1240 \r
1241 \r
1242                                         //bprint(ftos(time), " - flame transfer - ", ftos(flametime), "\n");\r
1243 \r
1244                                         \r
1245                                         IgniteTarget(head, self.owner, flametime, self.dmg, self.ltime, TRUE);\r
1246                                 }\r
1247                         }\r
1248                 }\r
1249                 head = head.chain;\r
1250         }\r
1251 }\r
1252 \r
1253 \r
1254 void PoisonTarget(entity targ, float poisonDamage, float poisonTime, float ratepoison)\r
1255 {\r
1256         if(targ.class == CLASS_MEDIC)\r
1257         {\r
1258                 return; // don't poison medics\r
1259         }\r
1260 \r
1261         if(ratepoison && targ.poison_damage > poisonDamage)\r
1262                 return; // current damage rating is larger, don't replace it\r
1263 \r
1264         targ.poison_damage = poisonDamage;\r
1265         targ.poison_rate = poisonDamage / poisonTime;\r
1266 }\r
1267 \r
1268 \r
1269 \r
1270 \r
1271 \r
1272 \r
1273 \r
1274 \r
1275 \r
1276 \r
1277 \r
1278 float W_LimitNumEnts(string clname, float num_allowed, void() DeathFunc)\r
1279 {\r
1280         float num, oldest;\r
1281         local entity e, selected;\r
1282         e = world;\r
1283         oldest = time + 1;\r
1284         num = 0;\r
1285         do\r
1286         {\r
1287                 e = find(e, classname, clname);\r
1288                 if(e != world && e.owner == self)\r
1289                 {\r
1290                         num = num + 1;\r
1291                         if(e.create_time < oldest)\r
1292                         {\r
1293                                 selected = e;\r
1294                                 oldest = e.create_time;\r
1295                         }\r
1296                 }\r
1297         }while(e);\r
1298 \r
1299         if(num > num_allowed)\r
1300         {\r
1301                 if(selected != world)\r
1302                 {\r
1303                         e = self;\r
1304                         self = selected;\r
1305                         DeathFunc();\r
1306                         self = e;\r
1307                         return TRUE;\r
1308                 }\r
1309                 else\r
1310                         bprint("error (W_LimitNumEnts): cannot find oldest entity\n");\r
1311         }\r
1312         return FALSE;\r
1313 }\r
1314 \r