]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/g_world.c
- Added more code for "maprules" entity which controls team/class restrictions on...
[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         // Misc TN Stuff\r
227         precache_model ("models/team/team.sp2");\r
228 \r
229 \r
230         // plays music for the level if there is any\r
231         if (self.noise)\r
232         {\r
233                 precache_sound (self.noise);\r
234                 ambientsound ('0 0 0', self.noise, 1.00, ATTN_NONE);\r
235         }\r
236 \r
237                 // 0 normal\r
238         lightstyle(0, "m");\r
239 \r
240         // 1 FLICKER (first variety)\r
241         lightstyle(1, "mmnmmommommnonmmonqnmmo");\r
242 \r
243         // 2 SLOW STRONG PULSE\r
244         lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");\r
245 \r
246         // 3 CANDLE (first variety)\r
247         lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");\r
248 \r
249         // 4 FAST STROBE\r
250         lightstyle(4, "mamamamamama");\r
251 \r
252         // 5 GENTLE PULSE 1\r
253         lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");\r
254 \r
255         // 6 FLICKER (second variety)\r
256         lightstyle(6, "nmonqnmomnmomomno");\r
257 \r
258         // 7 CANDLE (second variety)\r
259         lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");\r
260 \r
261         // 8 CANDLE (third variety)\r
262         lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");\r
263 \r
264         // 9 SLOW STROBE (fourth variety)\r
265         lightstyle(9, "aaaaaaaazzzzzzzz");\r
266 \r
267         // 10 FLUORESCENT FLICKER\r
268         lightstyle(10, "mmamammmmammamamaaamammma");\r
269 \r
270         // 11 SLOW PULSE NOT FADE TO BLACK\r
271         lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");\r
272 \r
273         // styles 32-62 are assigned by the light program for switchable lights\r
274 \r
275         // 63 testing\r
276         lightstyle(63, "a");\r
277 \r
278         if (cvar("g_domination"))\r
279                 dom_init();\r
280 }\r
281 \r
282 /* // spawn redirect function; doesn't work!\r
283 entity spawn()\r
284 {\r
285         entity e;\r
286         e = spawn_real();\r
287         e.create_time = time;\r
288         return e;\r
289 }*/\r
290 \r
291 void light (void)\r
292 {\r
293         makestatic (self);\r
294 }\r
295 \r
296 \r
297 // reads and alters data/maplist.cfg (sliding it one line), and returns a\r
298 // strzoned string containing the next map\r
299 #define MAPLIST "maplist.cfg"\r
300 string() Nex_RotateMapList =\r
301 {\r
302         local float lHandle;\r
303         local string lNextMap;\r
304         local string lCurrentMap;\r
305         local string lBuffer;\r
306 \r
307         lHandle = fopen( MAPLIST, FILE_READ );\r
308         if( lHandle < 0 ) {\r
309                 fclose( lHandle );\r
310                 // restart the current map if no other map is not found\r
311                 return strzone( mapname );\r
312         }\r
313 \r
314         // get the first line that will be moved to the end later\r
315         lCurrentMap = strzone( fgets( lHandle ) );\r
316         if( !lCurrentMap ) {\r
317                 fclose( lHandle );\r
318                 // restart the current map if no other map is not found\r
319                 return strzone( mapname );\r
320         }\r
321 \r
322         // now get the second line which is the map that should be loaded next\r
323         lBuffer = fgets( lHandle );\r
324         // if there isnt a second line, nothing needs to be rotated\r
325         if( !lBuffer ) {\r
326                 fclose( lHandle );\r
327                 strunzone( lCurrentMap );\r
328                 // restart the current map if no other map is not found\r
329                 return strzone( mapname );\r
330         }\r
331 \r
332         // since lBuffer holds the next map, it is assigned to nextmap\r
333         lNextMap = strzone( lBuffer );\r
334 \r
335         // since fgets uses its own buffer we need to move lBuffer to a tempstring\r
336         // before reading the next line (or lBuffer will be lost)\r
337         lBuffer = strcat( lBuffer );\r
338 \r
339         // read in the rest of the list\r
340         while( 1 )  {\r
341                 local string lLine;\r
342 \r
343                 lLine = fgets( lHandle );\r
344                 if( !lLine ) {\r
345                         break;\r
346                 }\r
347 \r
348                 lBuffer = strcat( lBuffer, "\n", lLine );\r
349         }\r
350         // rotate the list\r
351         lBuffer = strcat( lBuffer, "\n", lCurrentMap );\r
352 \r
353         // dismiss lCurrentmap now\r
354         strunzone( lCurrentMap );\r
355 \r
356         // and close the file handle\r
357         fclose( lHandle );\r
358 \r
359         // open the maplist for output this one\r
360         lHandle = fopen( MAPLIST, FILE_WRITE );\r
361         if( lHandle < 0 ) {\r
362                 // this shouldnt happen!\r
363                 // print a warning/error message\r
364                 dprint( "Couldn't open ", MAPLIST, " for output!\n" );\r
365 \r
366                 strunzone( lNextMap );\r
367 \r
368                 // we return the currently running map\r
369                 return strzone( mapname );\r
370         }\r
371 \r
372         fputs( lHandle, lBuffer );\r
373 \r
374         fclose( lHandle );\r
375 \r
376         return lNextMap;\r
377 };\r
378 \r
379 float gameover;\r
380 float intermission_running;\r
381 //float intermission_exittime;\r
382 float alreadychangedlevel;\r
383 \r
384 \r
385 void() GotoNextMap =\r
386 {\r
387         local string nextmap;\r
388         //local float n, nummaps;\r
389         //local string s;\r
390         if (alreadychangedlevel)\r
391                 return;\r
392         alreadychangedlevel = TRUE;\r
393         if (cvar("samelevel"))  // if samelevel is set, stay on same level\r
394                 changelevel (mapname);\r
395         else\r
396         {\r
397                 // method 1\r
398 \r
399                 //local entity pos;\r
400                 local float fh;\r
401                 local string line;\r
402 \r
403                 // restart current map if no cycle is found\r
404                 nextmap = strzone(mapname);\r
405                 fh = fopen("maplist.cfg", FILE_READ);\r
406                 if (fh >= 0)\r
407                 {\r
408                         while (1)\r
409                         {\r
410                                 line = fgets(fh);\r
411                                 if (nextmap == mapname)\r
412                                 {\r
413                                         strunzone(nextmap);\r
414                                         nextmap = strzone(line);\r
415                                 }\r
416                                 if (!line)\r
417                                         break;\r
418                                 if (line == mapname)\r
419                                 {\r
420                                         line = fgets(fh);\r
421                                         if (!line)\r
422                                                 break;\r
423                                         strunzone(nextmap);\r
424                                         nextmap = strzone(line);\r
425                                         break;\r
426                                 }\r
427                         }\r
428                         fclose(fh);\r
429                 }\r
430                 changelevel (nextmap);\r
431                 strunzone(nextmap);\r
432 \r
433                 // method 2\r
434                 //nextmap = Nex_RotateMapList();\r
435                 //changelevel (nextmap);\r
436                 //strunzone (nextmap);\r
437                 // method 3\r
438                 /*\r
439                 s = cvar_string("g_maplist");\r
440                 nummaps = tokenize(s);\r
441                 // if no map list, restart current one\r
442                 nextmap = mapname;\r
443                 if (nummaps >= 1)\r
444                 {\r
445                         n = 0;\r
446                         while (n < nummaps)\r
447                         {\r
448                                 if (argv(n) == mapname)\r
449                                         break;\r
450                                 n = n + 1;\r
451                         }\r
452                         n = n + 1;\r
453                         if (n >= nummaps)\r
454                                 n = 0;\r
455                         nextmap = argv(n);\r
456                 }\r
457                 changelevel (nextmap);\r
458                 */\r
459         }\r
460 };\r
461 \r
462 \r
463 /*\r
464 ============\r
465 IntermissionThink\r
466 \r
467 When the player presses attack or jump, change to the next level\r
468 ============\r
469 */\r
470 void() IntermissionThink =\r
471 {\r
472         if (time < intermission_exittime)\r
473                 return;\r
474 \r
475         if (time < intermission_exittime + 10 && !self.button0 && !self.button1 && !self.button2 && !self.button3)\r
476                 return;\r
477 \r
478         GotoNextMap ();\r
479 };\r
480 \r
481 /*\r
482 ============\r
483 FindIntermission\r
484 \r
485 Returns the entity to view from\r
486 ============\r
487 */\r
488 /*\r
489 entity() FindIntermission =\r
490 {\r
491         local   entity spot;\r
492         local   float cyc;\r
493 \r
494 // look for info_intermission first\r
495         spot = find (world, classname, "info_intermission");\r
496         if (spot)\r
497         {       // pick a random one\r
498                 cyc = random() * 4;\r
499                 while (cyc > 1)\r
500                 {\r
501                         spot = find (spot, classname, "info_intermission");\r
502                         if (!spot)\r
503                                 spot = find (spot, classname, "info_intermission");\r
504                         cyc = cyc - 1;\r
505                 }\r
506                 return spot;\r
507         }\r
508 \r
509 // then look for the start position\r
510         spot = find (world, classname, "info_player_start");\r
511         if (spot)\r
512                 return spot;\r
513 \r
514 // testinfo_player_start is only found in regioned levels\r
515         spot = find (world, classname, "testplayerstart");\r
516         if (spot)\r
517                 return spot;\r
518 \r
519 // then look for the start position\r
520         spot = find (world, classname, "info_player_deathmatch");\r
521         if (spot)\r
522                 return spot;\r
523 \r
524         //objerror ("FindIntermission: no spot");\r
525         return world;\r
526 };\r
527 */\r
528 \r
529 /*\r
530 ===============================================================================\r
531 \r
532 RULES\r
533 \r
534 ===============================================================================\r
535 */\r
536 \r
537 /*\r
538 go to the next level for deathmatch\r
539 only called if a time or frag limit has expired\r
540 */\r
541 void() NextLevel =\r
542 {\r
543         gameover = TRUE;\r
544 \r
545         intermission_running = 1;\r
546 \r
547 // enforce a wait time before allowing changelevel\r
548         intermission_exittime = time + 5;\r
549 \r
550         WriteByte (MSG_ALL, SVC_CDTRACK);\r
551         WriteByte (MSG_ALL, 3);\r
552         WriteByte (MSG_ALL, 3);\r
553 \r
554         //pos = FindIntermission ();\r
555 \r
556         other = find (world, classname, "player");\r
557         while (other != world)\r
558         {\r
559                 //other.nextthink = time + 0.5;\r
560                 other.takedamage = DAMAGE_NO;\r
561                 other.solid = SOLID_NOT;\r
562                 other.movetype = MOVETYPE_NONE;\r
563                 other.angles = other.v_angle;\r
564                 other.angles_x = other.angles_x * -1;\r
565                 /*\r
566                 if (pos != world);\r
567                 {\r
568                         other.modelindex = 0;\r
569                         other.weaponentity = world; // remove weapon model\r
570                         other.view_ofs = '0 0 0';\r
571                         other.angles = other.v_angle = pos.mangle;\r
572                         if (!other.angles)\r
573                         {\r
574                                 other.angles = other.v_angle = pos.angles;\r
575                                 other.v_angle_x = other.v_angle_x * -1;\r
576                         }\r
577                         other.fixangle = TRUE;          // turn this way immediately\r
578                         setorigin (other, pos.origin);\r
579                 }\r
580                 */\r
581                 other = find (other, classname, "player");\r
582         }\r
583 \r
584         WriteByte (MSG_ALL, SVC_INTERMISSION);\r
585 };\r
586 \r
587 /*\r
588 ============\r
589 CheckRules_Player\r
590 \r
591 Exit deathmatch games upon conditions\r
592 ============\r
593 */\r
594 void() CheckRules_Player =\r
595 {\r
596         local float fraglimit;\r
597 \r
598         if (gameover)   // someone else quit the game already\r
599                 return;\r
600 \r
601         fraglimit = cvar("fraglimit");\r
602         if (fraglimit && self.frags >= fraglimit)\r
603         {\r
604                 NextLevel ();\r
605                 return;\r
606         }\r
607 };\r
608 \r
609 float checkrules_oneminutewarning;\r
610 float checkrules_leaderfrags;\r
611 entity checkrules_leader;\r
612 \r
613 /*\r
614 ============\r
615 CheckRules_World\r
616 \r
617 Exit deathmatch games upon conditions\r
618 ============\r
619 */\r
620 void() CheckRules_World =\r
621 {\r
622         local float timelimit;\r
623         local float fraglimit;\r
624         local float checkrules_oldleaderfrags;\r
625         local entity checkrules_oldleader;\r
626         local entity head;\r
627 \r
628         if (intermission_running)\r
629         if (time >= intermission_exittime + 60)\r
630         {\r
631                 GotoNextMap();\r
632                 return;\r
633         }\r
634 \r
635         if (gameover)   // someone else quit the game already\r
636                 return;\r
637 \r
638         timelimit = cvar("timelimit") * 60;\r
639         fraglimit = cvar("fraglimit");\r
640 \r
641         if (timelimit && time >= timelimit)\r
642         {\r
643                 NextLevel ();\r
644                 return;\r
645         }\r
646 \r
647         if (!checkrules_oneminutewarning && timelimit && time > timelimit - 60)\r
648         {\r
649                 checkrules_oneminutewarning = TRUE;\r
650                 sound(world, CHAN_AUTO, "announcer/1minuteremains.wav", 1, ATTN_NONE);\r
651         }\r
652 \r
653         checkrules_oldleader = checkrules_leader;\r
654         checkrules_oldleaderfrags = checkrules_leaderfrags;\r
655         checkrules_leaderfrags = 0;\r
656         checkrules_leader = world;\r
657         head = findchain(classname, "player");\r
658         while (head)\r
659         {\r
660                 if (checkrules_leaderfrags < head.frags)\r
661                 {\r
662                         checkrules_leaderfrags = head.frags;\r
663                         checkrules_leader = head;\r
664                 }\r
665                 head = head.chain;\r
666         }\r
667         if (checkrules_leaderfrags <= 0)\r
668         {\r
669                 checkrules_leader = world;\r
670                 checkrules_leaderfrags = 0;\r
671         }\r
672         checkrules_leaderfrags = floor(checkrules_leaderfrags);\r
673         if (checkrules_leaderfrags != checkrules_oldleaderfrags)\r
674         {\r
675                 if (checkrules_leaderfrags == fraglimit - 1)\r
676                         sound(world, CHAN_AUTO, "announcer/1fragleft.wav", 1, ATTN_NONE);\r
677                 else if (checkrules_leaderfrags == fraglimit - 2)\r
678                         sound(world, CHAN_AUTO, "announcer/2fragsleft.wav", 1, ATTN_NONE);\r
679                 else if (checkrules_leaderfrags == fraglimit - 3)\r
680                         sound(world, CHAN_AUTO, "announcer/3fragsleft.wav", 1, ATTN_NONE);\r
681         }\r
682 //      if (checkrules_leader != checkrules_oldleader)// && checkrules_leaderfrags > checkrules_oldleaderfrags)\r
683 //              bprint("^1",checkrules_leader.netname, " has taken the lead with ", ftos(checkrules_leaderfrags), " frags\n");\r
684 };\r
685 \r