]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/g_world.c
- Improved accuracy of Rail Gun. Note: it still looks a bit off so sooner or later...
[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 \r
124         precache_model ("models/weapons/w_rli.zym");\r
125         precache_model ("models/weapons/w_flamer.zym");\r
126         precache_model ("models/weapons/w_bombletts.zym");\r
127         precache_model ("models/weapons/w_hotbombs.zym");\r
128         precache_model ("models/weapons/w_grapple.zym");\r
129         precache_model ("models/weapons/w_namek.zym");\r
130         precache_model ("models/weapons/w_railgun.zym");\r
131         precache_model ("models/weapons/w_mac.zym");\r
132 \r
133 \r
134         // other stuff\r
135         precache_model ("models/weapons/namekb.mdl");\r
136         precache_sound ("weapons/namek_fire.wav");\r
137 \r
138         precache_model ("models/misc/shield_s.mdl");\r
139 \r
140         precache_model ("models/misc/ropebase.mdl");\r
141 \r
142         // on fire sprites\r
143         precache_model ("models/sprites/fire_base.spr32");\r
144         precache_model ("models/sprites/fire_top.spr32");\r
145 \r
146         precache_model ("models/sprites/null.spr");\r
147 \r
148 \r
149         precache_sound ("announcer/1fragleft.wav");\r
150         precache_sound ("announcer/1minuteremains.wav");\r
151         precache_sound ("announcer/2fragsleft.wav");\r
152         precache_sound ("announcer/3fragsleft.wav");\r
153         precache_sound ("announcer/welcometonexuiz.wav");\r
154         precache_sound ("misc/armor1.wav");\r
155         precache_sound ("misc/armor25.wav");\r
156         precache_sound ("misc/armorimpact.wav");\r
157         precache_sound ("misc/bodyimpact1.wav");\r
158         precache_sound ("misc/bodyimpact2.wav");\r
159         precache_sound ("misc/gib.wav");\r
160         precache_sound ("misc/gib_splat01.wav");\r
161         precache_sound ("misc/gib_splat02.wav");\r
162         precache_sound ("misc/gib_splat03.wav");\r
163         precache_sound ("misc/gib_splat04.wav");\r
164         //precache_sound ("misc/h2ohit.wav");\r
165         precache_sound ("misc/hit.wav");\r
166         precache_sound ("misc/hitground1.wav");\r
167         precache_sound ("misc/hitground2.wav");\r
168         precache_sound ("misc/hitground3.wav");\r
169         precache_sound ("misc/hitground4.wav");\r
170         precache_sound ("misc/itempickup.wav");\r
171         precache_sound ("misc/itemrespawn.wav");\r
172         precache_sound ("misc/jumppad.wav");\r
173         precache_sound ("misc/mediumhealth.wav");\r
174         precache_sound ("misc/megahealth.wav");\r
175         precache_sound ("misc/minihealth.wav");\r
176         precache_sound ("misc/powerup.wav");\r
177         precache_sound ("misc/talk.wav");\r
178         precache_sound ("misc/teleport.wav");\r
179         precache_sound ("plats/medplat1.wav");\r
180         precache_sound ("plats/medplat2.wav");\r
181         precache_sound ("player/lava.wav");\r
182         precache_sound ("player/slime.wav");\r
183         precache_sound ("weapons/crylink.wav");\r
184         precache_sound ("weapons/crylink2.wav");\r
185         precache_sound ("weapons/electro_fire.wav");\r
186         precache_sound ("weapons/electro_fly.wav");\r
187         precache_sound ("weapons/electro_impact.wav");\r
188         precache_sound ("weapons/grenade_bounce.wav");\r
189         precache_sound ("weapons/grenade_fire.wav");\r
190         precache_sound ("weapons/grenade_impact.wav");\r
191         precache_sound ("weapons/hagar_fire.wav");\r
192         precache_sound ("weapons/hagexp1.wav");\r
193         precache_sound ("weapons/hagexp2.wav");\r
194         precache_sound ("weapons/hagexp3.wav");\r
195         precache_sound ("weapons/lasergun_fire.wav");\r
196         precache_sound ("weapons/laserimpact.wav");\r
197         precache_sound ("weapons/nexfire.wav");\r
198         precache_sound ("weapons/neximpact.wav");\r
199         precache_sound ("weapons/ric1.wav");\r
200         precache_sound ("weapons/ric2.wav");\r
201         precache_sound ("weapons/ric3.wav");\r
202         precache_sound ("weapons/rocket_fire.wav");\r
203         precache_sound ("weapons/rocket_fly.wav");\r
204         precache_sound ("weapons/rocket_impact.wav");\r
205         precache_sound ("weapons/shotgun_fire.wav");\r
206         precache_sound ("weapons/shotgun_reload.wav");\r
207         precache_sound ("weapons/tink1.wav");\r
208         precache_sound ("weapons/uzi_fire.wav");\r
209         precache_sound ("weapons/weapon_switch.wav");\r
210         precache_sound ("weapons/weaponpickup.wav");\r
211         precache_sound ("weapons/flamer.wav");\r
212         // TF SOUNDS & MODELS\r
213         precache_sound ("weapons/prime.wav");\r
214         precache_sound ("weapons/gren.wav");\r
215         precache_sound ("weapons/bounce.wav");\r
216 //      precache_sound ("player/step1l.wav");\r
217         precache_sound ("weapons/throw.wav");\r
218         precache_model ("progs/hgren2.mdl");\r
219         precache_model ("models/ammo/grenade/grenade.md3");\r
220         precache_model ("models/grenades/fragnade.md3");\r
221         precache_model ("models/magmine/magnetmine.md3");               // mag mine\r
222         precache_model ("models/sentry/turr1_barrel.md3");\r
223 \r
224 \r
225         // plays music for the level if there is any\r
226         if (self.noise)\r
227         {\r
228                 precache_sound (self.noise);\r
229                 ambientsound ('0 0 0', self.noise, 1.00, ATTN_NONE);\r
230         }\r
231 \r
232                 // 0 normal\r
233         lightstyle(0, "m");\r
234 \r
235         // 1 FLICKER (first variety)\r
236         lightstyle(1, "mmnmmommommnonmmonqnmmo");\r
237 \r
238         // 2 SLOW STRONG PULSE\r
239         lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");\r
240 \r
241         // 3 CANDLE (first variety)\r
242         lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");\r
243 \r
244         // 4 FAST STROBE\r
245         lightstyle(4, "mamamamamama");\r
246 \r
247         // 5 GENTLE PULSE 1\r
248         lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");\r
249 \r
250         // 6 FLICKER (second variety)\r
251         lightstyle(6, "nmonqnmomnmomomno");\r
252 \r
253         // 7 CANDLE (second variety)\r
254         lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");\r
255 \r
256         // 8 CANDLE (third variety)\r
257         lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");\r
258 \r
259         // 9 SLOW STROBE (fourth variety)\r
260         lightstyle(9, "aaaaaaaazzzzzzzz");\r
261 \r
262         // 10 FLUORESCENT FLICKER\r
263         lightstyle(10, "mmamammmmammamamaaamammma");\r
264 \r
265         // 11 SLOW PULSE NOT FADE TO BLACK\r
266         lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");\r
267 \r
268         // styles 32-62 are assigned by the light program for switchable lights\r
269 \r
270         // 63 testing\r
271         lightstyle(63, "a");\r
272 \r
273         if (cvar("g_domination"))\r
274                 dom_init();\r
275 }\r
276 \r
277 /* // spawn redirect function; doesn't work!\r
278 entity spawn()\r
279 {\r
280         entity e;\r
281         e = spawn_real();\r
282         e.create_time = time;\r
283         return e;\r
284 }*/\r
285 \r
286 void light (void)\r
287 {\r
288         makestatic (self);\r
289 }\r
290 \r
291 \r
292 // reads and alters data/maplist.cfg (sliding it one line), and returns a\r
293 // strzoned string containing the next map\r
294 #define MAPLIST "maplist.cfg"\r
295 string() Nex_RotateMapList =\r
296 {\r
297         local float lHandle;\r
298         local string lNextMap;\r
299         local string lCurrentMap;\r
300         local string lBuffer;\r
301 \r
302         lHandle = fopen( MAPLIST, FILE_READ );\r
303         if( lHandle < 0 ) {\r
304                 fclose( lHandle );\r
305                 // restart the current map if no other map is not found\r
306                 return strzone( mapname );\r
307         }\r
308 \r
309         // get the first line that will be moved to the end later\r
310         lCurrentMap = strzone( fgets( lHandle ) );\r
311         if( !lCurrentMap ) {\r
312                 fclose( lHandle );\r
313                 // restart the current map if no other map is not found\r
314                 return strzone( mapname );\r
315         }\r
316 \r
317         // now get the second line which is the map that should be loaded next\r
318         lBuffer = fgets( lHandle );\r
319         // if there isnt a second line, nothing needs to be rotated\r
320         if( !lBuffer ) {\r
321                 fclose( lHandle );\r
322                 strunzone( lCurrentMap );\r
323                 // restart the current map if no other map is not found\r
324                 return strzone( mapname );\r
325         }\r
326 \r
327         // since lBuffer holds the next map, it is assigned to nextmap\r
328         lNextMap = strzone( lBuffer );\r
329 \r
330         // since fgets uses its own buffer we need to move lBuffer to a tempstring\r
331         // before reading the next line (or lBuffer will be lost)\r
332         lBuffer = strcat( lBuffer );\r
333 \r
334         // read in the rest of the list\r
335         while( 1 )  {\r
336                 local string lLine;\r
337 \r
338                 lLine = fgets( lHandle );\r
339                 if( !lLine ) {\r
340                         break;\r
341                 }\r
342 \r
343                 lBuffer = strcat( lBuffer, "\n", lLine );\r
344         }\r
345         // rotate the list\r
346         lBuffer = strcat( lBuffer, "\n", lCurrentMap );\r
347 \r
348         // dismiss lCurrentmap now\r
349         strunzone( lCurrentMap );\r
350 \r
351         // and close the file handle\r
352         fclose( lHandle );\r
353 \r
354         // open the maplist for output this one\r
355         lHandle = fopen( MAPLIST, FILE_WRITE );\r
356         if( lHandle < 0 ) {\r
357                 // this shouldnt happen!\r
358                 // print a warning/error message\r
359                 dprint( "Couldn't open ", MAPLIST, " for output!\n" );\r
360 \r
361                 strunzone( lNextMap );\r
362 \r
363                 // we return the currently running map\r
364                 return strzone( mapname );\r
365         }\r
366 \r
367         fputs( lHandle, lBuffer );\r
368 \r
369         fclose( lHandle );\r
370 \r
371         return lNextMap;\r
372 };\r
373 \r
374 float gameover;\r
375 float intermission_running;\r
376 //float intermission_exittime;\r
377 float alreadychangedlevel;\r
378 \r
379 \r
380 void() GotoNextMap =\r
381 {\r
382         local string nextmap;\r
383         //local float n, nummaps;\r
384         //local string s;\r
385         if (alreadychangedlevel)\r
386                 return;\r
387         alreadychangedlevel = TRUE;\r
388         if (cvar("samelevel"))  // if samelevel is set, stay on same level\r
389                 changelevel (mapname);\r
390         else\r
391         {\r
392                 // method 1\r
393 \r
394                 //local entity pos;\r
395                 local float fh;\r
396                 local string line;\r
397 \r
398                 // restart current map if no cycle is found\r
399                 nextmap = strzone(mapname);\r
400                 fh = fopen("maplist.cfg", FILE_READ);\r
401                 if (fh >= 0)\r
402                 {\r
403                         while (1)\r
404                         {\r
405                                 line = fgets(fh);\r
406                                 if (nextmap == mapname)\r
407                                 {\r
408                                         strunzone(nextmap);\r
409                                         nextmap = strzone(line);\r
410                                 }\r
411                                 if (!line)\r
412                                         break;\r
413                                 if (line == mapname)\r
414                                 {\r
415                                         line = fgets(fh);\r
416                                         if (!line)\r
417                                                 break;\r
418                                         strunzone(nextmap);\r
419                                         nextmap = strzone(line);\r
420                                         break;\r
421                                 }\r
422                         }\r
423                         fclose(fh);\r
424                 }\r
425                 changelevel (nextmap);\r
426                 strunzone(nextmap);\r
427 \r
428                 // method 2\r
429                 //nextmap = Nex_RotateMapList();\r
430                 //changelevel (nextmap);\r
431                 //strunzone (nextmap);\r
432                 // method 3\r
433                 /*\r
434                 s = cvar_string("g_maplist");\r
435                 nummaps = tokenize(s);\r
436                 // if no map list, restart current one\r
437                 nextmap = mapname;\r
438                 if (nummaps >= 1)\r
439                 {\r
440                         n = 0;\r
441                         while (n < nummaps)\r
442                         {\r
443                                 if (argv(n) == mapname)\r
444                                         break;\r
445                                 n = n + 1;\r
446                         }\r
447                         n = n + 1;\r
448                         if (n >= nummaps)\r
449                                 n = 0;\r
450                         nextmap = argv(n);\r
451                 }\r
452                 changelevel (nextmap);\r
453                 */\r
454         }\r
455 };\r
456 \r
457 \r
458 /*\r
459 ============\r
460 IntermissionThink\r
461 \r
462 When the player presses attack or jump, change to the next level\r
463 ============\r
464 */\r
465 void() IntermissionThink =\r
466 {\r
467         if (time < intermission_exittime)\r
468                 return;\r
469 \r
470         if (time < intermission_exittime + 10 && !self.button0 && !self.button1 && !self.button2 && !self.button3)\r
471                 return;\r
472 \r
473         GotoNextMap ();\r
474 };\r
475 \r
476 /*\r
477 ============\r
478 FindIntermission\r
479 \r
480 Returns the entity to view from\r
481 ============\r
482 */\r
483 /*\r
484 entity() FindIntermission =\r
485 {\r
486         local   entity spot;\r
487         local   float cyc;\r
488 \r
489 // look for info_intermission first\r
490         spot = find (world, classname, "info_intermission");\r
491         if (spot)\r
492         {       // pick a random one\r
493                 cyc = random() * 4;\r
494                 while (cyc > 1)\r
495                 {\r
496                         spot = find (spot, classname, "info_intermission");\r
497                         if (!spot)\r
498                                 spot = find (spot, classname, "info_intermission");\r
499                         cyc = cyc - 1;\r
500                 }\r
501                 return spot;\r
502         }\r
503 \r
504 // then look for the start position\r
505         spot = find (world, classname, "info_player_start");\r
506         if (spot)\r
507                 return spot;\r
508 \r
509 // testinfo_player_start is only found in regioned levels\r
510         spot = find (world, classname, "testplayerstart");\r
511         if (spot)\r
512                 return spot;\r
513 \r
514 // then look for the start position\r
515         spot = find (world, classname, "info_player_deathmatch");\r
516         if (spot)\r
517                 return spot;\r
518 \r
519         //objerror ("FindIntermission: no spot");\r
520         return world;\r
521 };\r
522 */\r
523 \r
524 /*\r
525 ===============================================================================\r
526 \r
527 RULES\r
528 \r
529 ===============================================================================\r
530 */\r
531 \r
532 /*\r
533 go to the next level for deathmatch\r
534 only called if a time or frag limit has expired\r
535 */\r
536 void() NextLevel =\r
537 {\r
538         gameover = TRUE;\r
539 \r
540         intermission_running = 1;\r
541 \r
542 // enforce a wait time before allowing changelevel\r
543         intermission_exittime = time + 5;\r
544 \r
545         WriteByte (MSG_ALL, SVC_CDTRACK);\r
546         WriteByte (MSG_ALL, 3);\r
547         WriteByte (MSG_ALL, 3);\r
548 \r
549         //pos = FindIntermission ();\r
550 \r
551         other = find (world, classname, "player");\r
552         while (other != world)\r
553         {\r
554                 //other.nextthink = time + 0.5;\r
555                 other.takedamage = DAMAGE_NO;\r
556                 other.solid = SOLID_NOT;\r
557                 other.movetype = MOVETYPE_NONE;\r
558                 other.angles = other.v_angle;\r
559                 other.angles_x = other.angles_x * -1;\r
560                 /*\r
561                 if (pos != world);\r
562                 {\r
563                         other.modelindex = 0;\r
564                         other.weaponentity = world; // remove weapon model\r
565                         other.view_ofs = '0 0 0';\r
566                         other.angles = other.v_angle = pos.mangle;\r
567                         if (!other.angles)\r
568                         {\r
569                                 other.angles = other.v_angle = pos.angles;\r
570                                 other.v_angle_x = other.v_angle_x * -1;\r
571                         }\r
572                         other.fixangle = TRUE;          // turn this way immediately\r
573                         setorigin (other, pos.origin);\r
574                 }\r
575                 */\r
576                 other = find (other, classname, "player");\r
577         }\r
578 \r
579         WriteByte (MSG_ALL, SVC_INTERMISSION);\r
580 };\r
581 \r
582 /*\r
583 ============\r
584 CheckRules_Player\r
585 \r
586 Exit deathmatch games upon conditions\r
587 ============\r
588 */\r
589 void() CheckRules_Player =\r
590 {\r
591         local float fraglimit;\r
592 \r
593         if (gameover)   // someone else quit the game already\r
594                 return;\r
595 \r
596         fraglimit = cvar("fraglimit");\r
597         if (fraglimit && self.frags >= fraglimit)\r
598         {\r
599                 NextLevel ();\r
600                 return;\r
601         }\r
602 };\r
603 \r
604 float checkrules_oneminutewarning;\r
605 float checkrules_leaderfrags;\r
606 entity checkrules_leader;\r
607 \r
608 /*\r
609 ============\r
610 CheckRules_World\r
611 \r
612 Exit deathmatch games upon conditions\r
613 ============\r
614 */\r
615 void() CheckRules_World =\r
616 {\r
617         local float timelimit;\r
618         local float fraglimit;\r
619         local float checkrules_oldleaderfrags;\r
620         local entity checkrules_oldleader;\r
621         local entity head;\r
622 \r
623         if (intermission_running)\r
624         if (time >= intermission_exittime + 60)\r
625         {\r
626                 GotoNextMap();\r
627                 return;\r
628         }\r
629 \r
630         if (gameover)   // someone else quit the game already\r
631                 return;\r
632 \r
633         timelimit = cvar("timelimit") * 60;\r
634         fraglimit = cvar("fraglimit");\r
635 \r
636         if (timelimit && time >= timelimit)\r
637         {\r
638                 NextLevel ();\r
639                 return;\r
640         }\r
641 \r
642         if (!checkrules_oneminutewarning && timelimit && time > timelimit - 60)\r
643         {\r
644                 checkrules_oneminutewarning = TRUE;\r
645                 sound(world, CHAN_AUTO, "announcer/1minuteremains.wav", 1, ATTN_NONE);\r
646         }\r
647 \r
648         checkrules_oldleader = checkrules_leader;\r
649         checkrules_oldleaderfrags = checkrules_leaderfrags;\r
650         checkrules_leaderfrags = 0;\r
651         checkrules_leader = world;\r
652         head = findchain(classname, "player");\r
653         while (head)\r
654         {\r
655                 if (checkrules_leaderfrags < head.frags)\r
656                 {\r
657                         checkrules_leaderfrags = head.frags;\r
658                         checkrules_leader = head;\r
659                 }\r
660                 head = head.chain;\r
661         }\r
662         if (checkrules_leaderfrags <= 0)\r
663         {\r
664                 checkrules_leader = world;\r
665                 checkrules_leaderfrags = 0;\r
666         }\r
667         checkrules_leaderfrags = floor(checkrules_leaderfrags);\r
668         if (checkrules_leaderfrags != checkrules_oldleaderfrags)\r
669         {\r
670                 if (checkrules_leaderfrags == fraglimit - 1)\r
671                         sound(world, CHAN_AUTO, "announcer/1fragleft.wav", 1, ATTN_NONE);\r
672                 else if (checkrules_leaderfrags == fraglimit - 2)\r
673                         sound(world, CHAN_AUTO, "announcer/2fragsleft.wav", 1, ATTN_NONE);\r
674                 else if (checkrules_leaderfrags == fraglimit - 3)\r
675                         sound(world, CHAN_AUTO, "announcer/3fragsleft.wav", 1, ATTN_NONE);\r
676         }\r
677 //      if (checkrules_leader != checkrules_oldleader)// && checkrules_leaderfrags > checkrules_oldleaderfrags)\r
678 //              bprint("^1",checkrules_leader.netname, " has taken the lead with ", ftos(checkrules_leaderfrags), " frags\n");\r
679 };\r
680 \r