]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/g_world.c
- Added new backpack/tfitem property -- item_backpack gives metal ammo when var...
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / g_world.c
1 entity  lastspawn;\r
2 \r
3 void() dom_init;\r
4 \r
5 void worldspawn (void)\r
6 {\r
7         // Precache all player models\r
8         // Workaround for "invisible players"\r
9         precache_model("models/class/engineer_male.zym");\r
10         precache_model("models/class/engineer_female.zym");\r
11         precache_model("models/class/engineer_other.zym");\r
12         precache_model("models/class/soldier_male.zym");\r
13         precache_model("models/class/soldier_female.zym");\r
14         precache_model("models/class/soldier_mechanical.zym");\r
15         precache_model("models/class/scout_male.zym");\r
16         precache_model("models/class/scout_female.zym");\r
17         precache_model("models/class/scout_mechanical.zym");\r
18         precache_model("models/class/medic_male.zym");\r
19         precache_model("models/class/medic_female.zym");\r
20         precache_model("models/class/medic_mechanical.zym");\r
21         precache_model("models/class/pyro_male.zym");\r
22         precache_model("models/class/pyro_female.zym");\r
23         precache_model("models/class/pyro_mechanical.zym");\r
24         precache_model("models/class/spy_male.zym");\r
25         precache_model("models/class/spy_female.zym");\r
26         precache_model("models/class/spy_mechanical.zym");\r
27 \r
28         lastspawn = world;\r
29 \r
30         // the gravity set here can be overwritten by <mapname>.cfg\r
31         if(world.gravity)\r
32         {\r
33                 cvar_set("sv_gravity", ftos(world.gravity));\r
34         }\r
35         else\r
36                 cvar_set("sv_gravity", "800");\r
37 \r
38         game = cvar ("gamecfg");        // load game options\r
39 \r
40         //precache_model ("progs/beam.mdl");\r
41         precache_model ("progs/beam.mdl");\r
42         precache_model ("models/bullet.mdl");\r
43         precache_model ("models/casing_bronze.mdl");\r
44         precache_model ("models/casing_shell.mdl");\r
45         precache_model ("models/casing_steel.mdl");\r
46         precache_model ("models/ebomb.mdl");\r
47         precache_model ("models/elaser.mdl");\r
48         precache_model ("models/flash.md3");\r
49         precache_model ("models/gibs/bloodyskull.md3");\r
50         precache_model ("models/gibs/chunk.mdl");\r
51         precache_model ("models/gibs/eye.md3");\r
52         precache_model ("models/gibs/gib1.md3");\r
53         precache_model ("models/gibs/gib2.md3");\r
54         precache_model ("models/gibs/gib3.md3");\r
55         precache_model ("models/gibs/gib4.md3");\r
56         precache_model ("models/gibs/gib5.md3");\r
57         precache_model ("models/gibs/gib6.md3");\r
58         precache_model ("models/grenademodel.md3");\r
59         precache_model ("models/hagarmissile.mdl");\r
60         precache_model ("models/items/a_bullets.mdl");\r
61         precache_model ("models/items/a_cells.md3");\r
62         precache_model ("models/items/a_rockets.md3");\r
63         precache_model ("models/items/a_shells.md3");\r
64         precache_model ("models/items/g_a1.md3");\r
65         precache_model ("models/items/g_a25.md3");\r
66         precache_model ("models/items/g_h1.md3");\r
67         precache_model ("models/items/g_h25.md3");\r
68         precache_model ("models/items/g_h100.md3");\r
69         precache_model ("models/items/g_invincible.md3");\r
70         precache_model ("models/items/g_strength.md3");\r
71         precache_model ("models/laser.mdl");\r
72         precache_model ("models/misc/chatbubble.spr");\r
73         precache_model ("models/nexflash.md3");\r
74         precache_model ("models/plasma.mdl");\r
75         precache_model ("models/plasmatrail.mdl");\r
76         precache_model ("models/rocket.md3");\r
77         precache_model ("models/sprites/grenadeexplosion.spr32");\r
78         precache_model ("models/sprites/hagarexplosion.spr32");\r
79         precache_model ("models/sprites/muzzleflash.spr32");\r
80         //precache_model ("models/sprites/plasmahitwall.spr32");\r
81         //precache_model ("models/sprites/plasmashot.spr32");\r
82         precache_model ("models/sprites/rocketexplosion.spr32");\r
83         precache_model ("models/tracer.mdl");\r
84         precache_model ("models/uziflash.md3");\r
85         precache_model ("models/weapons/g_crylink.md3");\r
86         precache_model ("models/weapons/g_electro.md3");\r
87         precache_model ("models/weapons/g_gl.md3");\r
88         precache_model ("models/weapons/g_hagar.md3");\r
89         precache_model ("models/weapons/g_nex.md3");\r
90         precache_model ("models/weapons/g_rl.md3");\r
91         precache_model ("models/weapons/g_shotgun.md3");\r
92         precache_model ("models/weapons/g_uzi.md3");\r
93         precache_model ("models/weapons/v_crylink.md3");\r
94         precache_model ("models/weapons/v_electro.md3");\r
95         precache_model ("models/weapons/v_gl.md3");\r
96         precache_model ("models/weapons/v_hagar.md3");\r
97         precache_model ("models/weapons/v_laser.md3");\r
98         precache_model ("models/weapons/v_nex.md3");\r
99         precache_model ("models/weapons/v_rl.md3");\r
100         precache_model ("models/weapons/v_shotgun.md3");\r
101         precache_model ("models/weapons/v_uzi.md3");\r
102         precache_model ("models/weapons/w_crylink.zym");\r
103         precache_model ("models/weapons/w_electro.zym");\r
104         precache_model ("models/weapons/w_gl.zym");\r
105         precache_model ("models/weapons/w_hagar.zym");\r
106         precache_model ("models/weapons/w_laser.zym");\r
107         precache_model ("models/weapons/w_nex.zym");\r
108         precache_model ("models/weapons/w_rl.zym");\r
109         precache_model ("models/weapons/w_shotgun.zym");\r
110         precache_model ("models/weapons/w_uzi.zym");\r
111 \r
112 \r
113 \r
114         // new weapon models\r
115         precache_model ("models/weapons/v_rli.md3");            // incendiary rockets\r
116         precache_model ("models/weapons/v_flamer.md3");         // flamer\r
117         precache_model ("models/weapons/v_bombletts.md3");      // bombletts\r
118         precache_model ("models/weapons/v_hotbombs.md3");       // hot bombs\r
119         precache_model ("models/weapons/v_grapple.md3");        // grappling hook\r
120         precache_model ("models/weapons/v_namek.md3");          // namek\r
121         precache_model ("models/weapons/v_railgun.md3");        // railgun (engineer)\r
122         precache_model ("models/weapons/v_mac.md3");            // MAC10 (spy)\r
123         precache_model ("models/weapons/v_soldpistol.md3");     // Pistol\r
124 \r
125         precache_model ("models/weapons/w_rli.zym");\r
126         precache_model ("models/weapons/w_flamer.zym");\r
127         precache_model ("models/weapons/w_bombletts.zym");\r
128         precache_model ("models/weapons/w_hotbombs.zym");\r
129         precache_model ("models/weapons/w_grapple.zym");\r
130         precache_model ("models/weapons/w_namek.zym");\r
131         precache_model ("models/weapons/w_railgun.zym");\r
132         precache_model ("models/weapons/w_mac.zym");\r
133         precache_model ("models/weapons/w_soldpistol.zym");\r
134 \r
135 \r
136         // other stuff\r
137         precache_model ("models/weapons/namekb.mdl");\r
138         precache_sound ("weapons/namek_fire.wav");\r
139 \r
140         precache_model ("models/misc/shield_s.mdl");\r
141 \r
142         precache_model ("models/misc/ropebase.mdl");\r
143 \r
144         // on fire sprites\r
145         precache_model ("models/sprites/fire_base.spr32");\r
146         precache_model ("models/sprites/fire_top.spr32");\r
147 \r
148         precache_model ("models/sprites/null.spr");\r
149 \r
150 \r
151         precache_sound ("announcer/1fragleft.wav");\r
152         precache_sound ("announcer/1minuteremains.wav");\r
153         precache_sound ("announcer/2fragsleft.wav");\r
154         precache_sound ("announcer/3fragsleft.wav");\r
155         precache_sound ("announcer/welcometonexuiz.wav");\r
156         precache_sound ("misc/armor1.wav");\r
157         precache_sound ("misc/armor25.wav");\r
158         precache_sound ("misc/armorimpact.wav");\r
159         precache_sound ("misc/bodyimpact1.wav");\r
160         precache_sound ("misc/bodyimpact2.wav");\r
161         precache_sound ("misc/gib.wav");\r
162         precache_sound ("misc/gib_splat01.wav");\r
163         precache_sound ("misc/gib_splat02.wav");\r
164         precache_sound ("misc/gib_splat03.wav");\r
165         precache_sound ("misc/gib_splat04.wav");\r
166         //precache_sound ("misc/h2ohit.wav");\r
167         precache_sound ("misc/hit.wav");\r
168         precache_sound ("misc/hitground1.wav");\r
169         precache_sound ("misc/hitground2.wav");\r
170         precache_sound ("misc/hitground3.wav");\r
171         precache_sound ("misc/hitground4.wav");\r
172         precache_sound ("misc/itempickup.wav");\r
173         precache_sound ("misc/itemrespawn.wav");\r
174         precache_sound ("misc/jumppad.wav");\r
175         precache_sound ("misc/mediumhealth.wav");\r
176         precache_sound ("misc/megahealth.wav");\r
177         precache_sound ("misc/minihealth.wav");\r
178         precache_sound ("misc/powerup.wav");\r
179         precache_sound ("misc/talk.wav");\r
180         precache_sound ("misc/teleport.wav");\r
181         precache_sound ("plats/medplat1.wav");\r
182         precache_sound ("plats/medplat2.wav");\r
183         precache_sound ("player/lava.wav");\r
184         precache_sound ("player/slime.wav");\r
185         precache_sound ("weapons/crylink.wav");\r
186         precache_sound ("weapons/crylink2.wav");\r
187         precache_sound ("weapons/electro_fire.wav");\r
188         precache_sound ("weapons/electro_fly.wav");\r
189         precache_sound ("weapons/electro_impact.wav");\r
190         precache_sound ("weapons/grenade_bounce.wav");\r
191         precache_sound ("weapons/grenade_fire.wav");\r
192         precache_sound ("weapons/grenade_impact.wav");\r
193         precache_sound ("weapons/hagar_fire.wav");\r
194         precache_sound ("weapons/hagexp1.wav");\r
195         precache_sound ("weapons/hagexp2.wav");\r
196         precache_sound ("weapons/hagexp3.wav");\r
197         precache_sound ("weapons/lasergun_fire.wav");\r
198         precache_sound ("weapons/laserimpact.wav");\r
199         precache_sound ("weapons/nexfire.wav");\r
200         precache_sound ("weapons/neximpact.wav");\r
201         precache_sound ("weapons/ric1.wav");\r
202         precache_sound ("weapons/ric2.wav");\r
203         precache_sound ("weapons/ric3.wav");\r
204         precache_sound ("weapons/rocket_fire.wav");\r
205         precache_sound ("weapons/rocket_fly.wav");\r
206         precache_sound ("weapons/rocket_impact.wav");\r
207         precache_sound ("weapons/shotgun_fire.wav");\r
208         precache_sound ("weapons/shotgun_reload.wav");\r
209         precache_sound ("weapons/tink1.wav");\r
210         precache_sound ("weapons/uzi_fire.wav");\r
211         precache_sound ("weapons/weapon_switch.wav");\r
212         precache_sound ("weapons/weaponpickup.wav");\r
213         precache_sound ("weapons/flamer.wav");\r
214         // TF SOUNDS & MODELS\r
215         precache_sound ("weapons/prime.wav");\r
216         precache_sound ("weapons/gren.wav");\r
217         precache_sound ("weapons/bounce.wav");\r
218 //      precache_sound ("player/step1l.wav");\r
219         precache_sound ("weapons/throw.wav");\r
220         precache_model ("progs/hgren2.mdl");\r
221         precache_model ("models/ammo/grenade/grenade.md3");\r
222         precache_model ("models/grenades/fragnade.md3");\r
223         precache_model ("models/magmine/magnetmine.md3");               // mag mine\r
224         precache_model ("models/sentry/turr1_barrel.md3");\r
225 \r
226 \r
227         // plays music for the level if there is any\r
228         if (self.noise)\r
229         {\r
230                 precache_sound (self.noise);\r
231                 ambientsound ('0 0 0', self.noise, 1.00, ATTN_NONE);\r
232         }\r
233 \r
234                 // 0 normal\r
235         lightstyle(0, "m");\r
236 \r
237         // 1 FLICKER (first variety)\r
238         lightstyle(1, "mmnmmommommnonmmonqnmmo");\r
239 \r
240         // 2 SLOW STRONG PULSE\r
241         lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");\r
242 \r
243         // 3 CANDLE (first variety)\r
244         lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");\r
245 \r
246         // 4 FAST STROBE\r
247         lightstyle(4, "mamamamamama");\r
248 \r
249         // 5 GENTLE PULSE 1\r
250         lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");\r
251 \r
252         // 6 FLICKER (second variety)\r
253         lightstyle(6, "nmonqnmomnmomomno");\r
254 \r
255         // 7 CANDLE (second variety)\r
256         lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");\r
257 \r
258         // 8 CANDLE (third variety)\r
259         lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");\r
260 \r
261         // 9 SLOW STROBE (fourth variety)\r
262         lightstyle(9, "aaaaaaaazzzzzzzz");\r
263 \r
264         // 10 FLUORESCENT FLICKER\r
265         lightstyle(10, "mmamammmmammamamaaamammma");\r
266 \r
267         // 11 SLOW PULSE NOT FADE TO BLACK\r
268         lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");\r
269 \r
270         // styles 32-62 are assigned by the light program for switchable lights\r
271 \r
272         // 63 testing\r
273         lightstyle(63, "a");\r
274 \r
275         if (cvar("g_domination"))\r
276                 dom_init();\r
277 }\r
278 \r
279 /* // spawn redirect function; doesn't work!\r
280 entity spawn()\r
281 {\r
282         entity e;\r
283         e = spawn_real();\r
284         e.create_time = time;\r
285         return e;\r
286 }*/\r
287 \r
288 void light (void)\r
289 {\r
290         makestatic (self);\r
291 }\r
292 \r
293 \r
294 // reads and alters data/maplist.cfg (sliding it one line), and returns a\r
295 // strzoned string containing the next map\r
296 #define MAPLIST "maplist.cfg"\r
297 string() Nex_RotateMapList =\r
298 {\r
299         local float lHandle;\r
300         local string lNextMap;\r
301         local string lCurrentMap;\r
302         local string lBuffer;\r
303 \r
304         lHandle = fopen( MAPLIST, FILE_READ );\r
305         if( lHandle < 0 ) {\r
306                 fclose( lHandle );\r
307                 // restart the current map if no other map is not found\r
308                 return strzone( mapname );\r
309         }\r
310 \r
311         // get the first line that will be moved to the end later\r
312         lCurrentMap = strzone( fgets( lHandle ) );\r
313         if( !lCurrentMap ) {\r
314                 fclose( lHandle );\r
315                 // restart the current map if no other map is not found\r
316                 return strzone( mapname );\r
317         }\r
318 \r
319         // now get the second line which is the map that should be loaded next\r
320         lBuffer = fgets( lHandle );\r
321         // if there isnt a second line, nothing needs to be rotated\r
322         if( !lBuffer ) {\r
323                 fclose( lHandle );\r
324                 strunzone( lCurrentMap );\r
325                 // restart the current map if no other map is not found\r
326                 return strzone( mapname );\r
327         }\r
328 \r
329         // since lBuffer holds the next map, it is assigned to nextmap\r
330         lNextMap = strzone( lBuffer );\r
331 \r
332         // since fgets uses its own buffer we need to move lBuffer to a tempstring\r
333         // before reading the next line (or lBuffer will be lost)\r
334         lBuffer = strcat( lBuffer );\r
335 \r
336         // read in the rest of the list\r
337         while( 1 )  {\r
338                 local string lLine;\r
339 \r
340                 lLine = fgets( lHandle );\r
341                 if( !lLine ) {\r
342                         break;\r
343                 }\r
344 \r
345                 lBuffer = strcat( lBuffer, "\n", lLine );\r
346         }\r
347         // rotate the list\r
348         lBuffer = strcat( lBuffer, "\n", lCurrentMap );\r
349 \r
350         // dismiss lCurrentmap now\r
351         strunzone( lCurrentMap );\r
352 \r
353         // and close the file handle\r
354         fclose( lHandle );\r
355 \r
356         // open the maplist for output this one\r
357         lHandle = fopen( MAPLIST, FILE_WRITE );\r
358         if( lHandle < 0 ) {\r
359                 // this shouldnt happen!\r
360                 // print a warning/error message\r
361                 dprint( "Couldn't open ", MAPLIST, " for output!\n" );\r
362 \r
363                 strunzone( lNextMap );\r
364 \r
365                 // we return the currently running map\r
366                 return strzone( mapname );\r
367         }\r
368 \r
369         fputs( lHandle, lBuffer );\r
370 \r
371         fclose( lHandle );\r
372 \r
373         return lNextMap;\r
374 };\r
375 \r
376 float gameover;\r
377 float intermission_running;\r
378 //float intermission_exittime;\r
379 float alreadychangedlevel;\r
380 \r
381 \r
382 void() GotoNextMap =\r
383 {\r
384         local string nextmap;\r
385         //local float n, nummaps;\r
386         //local string s;\r
387         if (alreadychangedlevel)\r
388                 return;\r
389         alreadychangedlevel = TRUE;\r
390         if (cvar("samelevel"))  // if samelevel is set, stay on same level\r
391                 changelevel (mapname);\r
392         else\r
393         {\r
394                 // method 1\r
395 \r
396                 //local entity pos;\r
397                 local float fh;\r
398                 local string line;\r
399 \r
400                 // restart current map if no cycle is found\r
401                 nextmap = strzone(mapname);\r
402                 fh = fopen("maplist.cfg", FILE_READ);\r
403                 if (fh >= 0)\r
404                 {\r
405                         while (1)\r
406                         {\r
407                                 line = fgets(fh);\r
408                                 if (nextmap == mapname)\r
409                                 {\r
410                                         strunzone(nextmap);\r
411                                         nextmap = strzone(line);\r
412                                 }\r
413                                 if (!line)\r
414                                         break;\r
415                                 if (line == mapname)\r
416                                 {\r
417                                         line = fgets(fh);\r
418                                         if (!line)\r
419                                                 break;\r
420                                         strunzone(nextmap);\r
421                                         nextmap = strzone(line);\r
422                                         break;\r
423                                 }\r
424                         }\r
425                         fclose(fh);\r
426                 }\r
427                 changelevel (nextmap);\r
428                 strunzone(nextmap);\r
429 \r
430                 // method 2\r
431                 //nextmap = Nex_RotateMapList();\r
432                 //changelevel (nextmap);\r
433                 //strunzone (nextmap);\r
434                 // method 3\r
435                 /*\r
436                 s = cvar_string("g_maplist");\r
437                 nummaps = tokenize(s);\r
438                 // if no map list, restart current one\r
439                 nextmap = mapname;\r
440                 if (nummaps >= 1)\r
441                 {\r
442                         n = 0;\r
443                         while (n < nummaps)\r
444                         {\r
445                                 if (argv(n) == mapname)\r
446                                         break;\r
447                                 n = n + 1;\r
448                         }\r
449                         n = n + 1;\r
450                         if (n >= nummaps)\r
451                                 n = 0;\r
452                         nextmap = argv(n);\r
453                 }\r
454                 changelevel (nextmap);\r
455                 */\r
456         }\r
457 };\r
458 \r
459 \r
460 /*\r
461 ============\r
462 IntermissionThink\r
463 \r
464 When the player presses attack or jump, change to the next level\r
465 ============\r
466 */\r
467 void() IntermissionThink =\r
468 {\r
469         if (time < intermission_exittime)\r
470                 return;\r
471 \r
472         if (time < intermission_exittime + 10 && !self.button0 && !self.button1 && !self.button2 && !self.button3)\r
473                 return;\r
474 \r
475         GotoNextMap ();\r
476 };\r
477 \r
478 /*\r
479 ============\r
480 FindIntermission\r
481 \r
482 Returns the entity to view from\r
483 ============\r
484 */\r
485 /*\r
486 entity() FindIntermission =\r
487 {\r
488         local   entity spot;\r
489         local   float cyc;\r
490 \r
491 // look for info_intermission first\r
492         spot = find (world, classname, "info_intermission");\r
493         if (spot)\r
494         {       // pick a random one\r
495                 cyc = random() * 4;\r
496                 while (cyc > 1)\r
497                 {\r
498                         spot = find (spot, classname, "info_intermission");\r
499                         if (!spot)\r
500                                 spot = find (spot, classname, "info_intermission");\r
501                         cyc = cyc - 1;\r
502                 }\r
503                 return spot;\r
504         }\r
505 \r
506 // then look for the start position\r
507         spot = find (world, classname, "info_player_start");\r
508         if (spot)\r
509                 return spot;\r
510 \r
511 // testinfo_player_start is only found in regioned levels\r
512         spot = find (world, classname, "testplayerstart");\r
513         if (spot)\r
514                 return spot;\r
515 \r
516 // then look for the start position\r
517         spot = find (world, classname, "info_player_deathmatch");\r
518         if (spot)\r
519                 return spot;\r
520 \r
521         //objerror ("FindIntermission: no spot");\r
522         return world;\r
523 };\r
524 */\r
525 \r
526 /*\r
527 ===============================================================================\r
528 \r
529 RULES\r
530 \r
531 ===============================================================================\r
532 */\r
533 \r
534 /*\r
535 go to the next level for deathmatch\r
536 only called if a time or frag limit has expired\r
537 */\r
538 void() NextLevel =\r
539 {\r
540         gameover = TRUE;\r
541 \r
542         intermission_running = 1;\r
543 \r
544 // enforce a wait time before allowing changelevel\r
545         intermission_exittime = time + 5;\r
546 \r
547         WriteByte (MSG_ALL, SVC_CDTRACK);\r
548         WriteByte (MSG_ALL, 3);\r
549         WriteByte (MSG_ALL, 3);\r
550 \r
551         //pos = FindIntermission ();\r
552 \r
553         other = find (world, classname, "player");\r
554         while (other != world)\r
555         {\r
556                 //other.nextthink = time + 0.5;\r
557                 other.takedamage = DAMAGE_NO;\r
558                 other.solid = SOLID_NOT;\r
559                 other.movetype = MOVETYPE_NONE;\r
560                 other.angles = other.v_angle;\r
561                 other.angles_x = other.angles_x * -1;\r
562                 /*\r
563                 if (pos != world);\r
564                 {\r
565                         other.modelindex = 0;\r
566                         other.weaponentity = world; // remove weapon model\r
567                         other.view_ofs = '0 0 0';\r
568                         other.angles = other.v_angle = pos.mangle;\r
569                         if (!other.angles)\r
570                         {\r
571                                 other.angles = other.v_angle = pos.angles;\r
572                                 other.v_angle_x = other.v_angle_x * -1;\r
573                         }\r
574                         other.fixangle = TRUE;          // turn this way immediately\r
575                         setorigin (other, pos.origin);\r
576                 }\r
577                 */\r
578                 other = find (other, classname, "player");\r
579         }\r
580 \r
581         WriteByte (MSG_ALL, SVC_INTERMISSION);\r
582 };\r
583 \r
584 /*\r
585 ============\r
586 CheckRules_Player\r
587 \r
588 Exit deathmatch games upon conditions\r
589 ============\r
590 */\r
591 void() CheckRules_Player =\r
592 {\r
593         local float fraglimit;\r
594 \r
595         if (gameover)   // someone else quit the game already\r
596                 return;\r
597 \r
598         fraglimit = cvar("fraglimit");\r
599         if (fraglimit && self.frags >= fraglimit)\r
600         {\r
601                 NextLevel ();\r
602                 return;\r
603         }\r
604 };\r
605 \r
606 float checkrules_oneminutewarning;\r
607 float checkrules_leaderfrags;\r
608 entity checkrules_leader;\r
609 \r
610 /*\r
611 ============\r
612 CheckRules_World\r
613 \r
614 Exit deathmatch games upon conditions\r
615 ============\r
616 */\r
617 void() CheckRules_World =\r
618 {\r
619         local float timelimit;\r
620         local float fraglimit;\r
621         local float checkrules_oldleaderfrags;\r
622         local entity checkrules_oldleader;\r
623         local entity head;\r
624 \r
625         if (intermission_running)\r
626         if (time >= intermission_exittime + 60)\r
627         {\r
628                 GotoNextMap();\r
629                 return;\r
630         }\r
631 \r
632         if (gameover)   // someone else quit the game already\r
633                 return;\r
634 \r
635         timelimit = cvar("timelimit") * 60;\r
636         fraglimit = cvar("fraglimit");\r
637 \r
638         if (timelimit && time >= timelimit)\r
639         {\r
640                 NextLevel ();\r
641                 return;\r
642         }\r
643 \r
644         if (!checkrules_oneminutewarning && timelimit && time > timelimit - 60)\r
645         {\r
646                 checkrules_oneminutewarning = TRUE;\r
647                 sound(world, CHAN_AUTO, "announcer/1minuteremains.wav", 1, ATTN_NONE);\r
648         }\r
649 \r
650         checkrules_oldleader = checkrules_leader;\r
651         checkrules_oldleaderfrags = checkrules_leaderfrags;\r
652         checkrules_leaderfrags = 0;\r
653         checkrules_leader = world;\r
654         head = findchain(classname, "player");\r
655         while (head)\r
656         {\r
657                 if (checkrules_leaderfrags < head.frags)\r
658                 {\r
659                         checkrules_leaderfrags = head.frags;\r
660                         checkrules_leader = head;\r
661                 }\r
662                 head = head.chain;\r
663         }\r
664         if (checkrules_leaderfrags <= 0)\r
665         {\r
666                 checkrules_leader = world;\r
667                 checkrules_leaderfrags = 0;\r
668         }\r
669         checkrules_leaderfrags = floor(checkrules_leaderfrags);\r
670         if (checkrules_leaderfrags != checkrules_oldleaderfrags)\r
671         {\r
672                 if (checkrules_leaderfrags == fraglimit - 1)\r
673                         sound(world, CHAN_AUTO, "announcer/1fragleft.wav", 1, ATTN_NONE);\r
674                 else if (checkrules_leaderfrags == fraglimit - 2)\r
675                         sound(world, CHAN_AUTO, "announcer/2fragsleft.wav", 1, ATTN_NONE);\r
676                 else if (checkrules_leaderfrags == fraglimit - 3)\r
677                         sound(world, CHAN_AUTO, "announcer/3fragsleft.wav", 1, ATTN_NONE);\r
678         }\r
679 //      if (checkrules_leader != checkrules_oldleader)// && checkrules_leaderfrags > checkrules_oldleaderfrags)\r
680 //              bprint("^1",checkrules_leader.netname, " has taken the lead with ", ftos(checkrules_leaderfrags), " frags\n");\r
681 };\r
682 \r