]> icculus.org git repositories - divverent/nexuiz.git/blob - TeamNexuiz/game/gamec/cl_client.c
- Updated weapon code for 1.5
[divverent/nexuiz.git] / TeamNexuiz / game / gamec / cl_client.c
1 void info_player_start (void)\r
2 {\r
3         if (self.allowteams != "")\r
4         {\r
5                 if (self.allowteams == "blue")\r
6                         self.team_no = 1;\r
7                 if (self.allowteams == "red")\r
8                         self.team_no = 2;\r
9                 if (!self.goal_state)\r
10                         self.goal_state = 1;\r
11                 if (!self.group_no)\r
12                         self.group_no = 1;\r
13                 i_p_t();\r
14                 return;\r
15         }\r
16         else\r
17         {\r
18                 self.classname = "info_player_deathmatch";\r
19         }\r
20 };\r
21 \r
22 void info_player_deathmatch (void)\r
23 {\r
24 }\r
25 /*\r
26 ===============\r
27  Find Team Spawn Point (NexTF!)\r
28                                  ===============\r
29 */\r
30 entity (float team_num) FindTeamSpawnPoint =\r
31 {\r
32         local entity spot;\r
33         local entity at_spot;\r
34         local float spot_found;\r
35         local float attempts;\r
36 \r
37         if ((team_num == 1))\r
38         {\r
39                 spot = lastspawn_team1;\r
40                 attempts = 0;\r
41                 while (1)\r
42                 {\r
43                         attempts = (attempts + 1);\r
44                         spot = find (spot, team_str_home, "ts1");\r
45                         if ((spot == world))\r
46                         {\r
47                                 spot = find (world, team_str_home, "ts1");\r
48                         }\r
49                         if ((spot == world))\r
50                         {\r
51                                 return (world);\r
52                         }\r
53                         at_spot = findradius (spot.origin, 40);\r
54                         spot_found = 1;\r
55                         while ((at_spot != world))\r
56                         {\r
57                                 if (((at_spot.classname == "player") && (at_spot.deadflag == 0)))\r
58                                 {\r
59                                         spot_found = 0;\r
60                                 }\r
61                                 at_spot = at_spot.chain;\r
62                         }\r
63                         if (!Activated (spot, self))\r
64                         {\r
65                                 spot_found = 0;\r
66                         }\r
67                         if ((spot_found || (attempts >= 30)))\r
68                         {\r
69                                 lastspawn_team1 = spot;\r
70                                 return (spot);\r
71                         }\r
72                 }\r
73         }\r
74         else\r
75         {\r
76                 if ((team_num == 2))\r
77                 {\r
78                         spot = lastspawn_team2;\r
79                         attempts = 0;\r
80                         while (1)\r
81                         {\r
82                                 attempts = (attempts + 1);\r
83                                 spot = find (spot, team_str_home, "ts2");\r
84                                 if ((spot == world))\r
85                                 {\r
86                                         spot = find (world, team_str_home, "ts2");\r
87                                 }\r
88                                 if ((spot == world))\r
89                                 {\r
90                                         return (world);\r
91                                 }\r
92                                 at_spot = findradius (spot.origin, 40);\r
93                                 spot_found = 1;\r
94                                 while ((at_spot != world))\r
95                                 {\r
96                                         if (((at_spot.classname == "player") && (at_spot.deadflag == 0)))\r
97                                         {\r
98                                                 spot_found = 0;\r
99                                         }\r
100                                         at_spot = at_spot.chain;\r
101                                 }\r
102                                 if (!Activated (spot, self))\r
103                                 {\r
104                                         spot_found = 0;\r
105                                 }\r
106                                 if ((spot_found || (attempts >= 30)))\r
107                                 {\r
108                                         lastspawn_team2 = spot;\r
109                                         return (spot);\r
110                                 }\r
111                         }\r
112                 }\r
113                 else\r
114                 {\r
115                         if ((team_num == 3))\r
116                         {\r
117                                 spot = lastspawn_team3;\r
118                                 attempts = 0;\r
119                                 while (1)\r
120                                 {\r
121                                         attempts = (attempts + 1);\r
122                                         spot = find (spot, team_str_home, "ts3");\r
123                                         if ((spot == world))\r
124                                         {\r
125                                                 spot = find (world, team_str_home, "ts3");\r
126                                         }\r
127                                         if ((spot == world))\r
128                                         {\r
129                                                 return (world);\r
130                                         }\r
131                                         at_spot = findradius (spot.origin, 40);\r
132                                         spot_found = 1;\r
133                                         while ((at_spot != world))\r
134                                         {\r
135                                                 if (((at_spot.classname == "player") && (at_spot.deadflag == 0)))\r
136                                                 {\r
137                                                         spot_found = 0;\r
138                                                 }\r
139                                                 at_spot = at_spot.chain;\r
140                                         }\r
141                                         if (!Activated (spot, self))\r
142                                         {\r
143                                                 spot_found = 0;\r
144                                         }\r
145                                         if ((spot_found || (attempts >= 30)))\r
146                                         {\r
147                                                 lastspawn_team3 = spot;\r
148                                                 return (spot);\r
149                                         }\r
150                                 }\r
151                         }\r
152                         else\r
153                         {\r
154                                 if ((team_num == 4))\r
155                                 {\r
156                                         spot = lastspawn_team4;\r
157                                         attempts = 0;\r
158                                         while (1)\r
159                                         {\r
160                                                 attempts = (attempts + 1);\r
161                                                 spot = find (spot, team_str_home, "ts4");\r
162                                                 if ((spot == world))\r
163                                                 {\r
164                                                         spot = find (world, team_str_home, "ts4");\r
165                                                 }\r
166                                                 if ((spot == world))\r
167                                                 {\r
168                                                         return (world);\r
169                                                 }\r
170                                                 at_spot = findradius (spot.origin, 40);\r
171                                                 spot_found = 1;\r
172                                                 while ((at_spot != world))\r
173                                                 {\r
174                                                         if (((at_spot.classname == "player") && (at_spot.deadflag == 0)))\r
175                                                         {\r
176                                                                 spot_found = 0;\r
177                                                         }\r
178                                                         at_spot = at_spot.chain;\r
179                                                 }\r
180                                                 if (!Activated (spot, self))\r
181                                                 {\r
182                                                         spot_found = 0;\r
183                                                 }\r
184                                                 if ((spot_found || (attempts >= 30)))\r
185                                                 {\r
186                                                         lastspawn_team4 = spot;\r
187                                                         return (spot);\r
188                                                 }\r
189                                         }\r
190                                 }\r
191                         }\r
192                 }\r
193         }\r
194         return (world);\r
195 };\r
196 \r
197 /*\r
198 =============\r
199 SelectSpawnPoint\r
200 \r
201 Finds a point to respawn\r
202 =============\r
203 */\r
204 entity () SelectSpawnPoint =\r
205 {\r
206         local entity spot;\r
207         local entity at_spot;\r
208         local float spot_found;\r
209         local float attempts;\r
210 \r
211         if (self.team_no < 1)\r
212         {\r
213 //              self.origin_z = self.origin_z + 30;\r
214                 if (!cvar("g_teamnexuiz_version"))\r
215                         self.current_menu = MENU_NEED_TN;\r
216 \r
217                 stuffcmd(self, "alias menu_showteamselect \"set scmenu_directmenu TeamSelect; togglemenu\"\n");\r
218                 stuffcmd(self, "set scmenu_directmenu TeamSelect; togglemenu\n");\r
219 \r
220                 stuffcmd(self, "alias classmenu \"impulse 73\"\n");\r
221 //              spot = find (world, classname, "item_tfgoal");\r
222 //              return (spot);\r
223         }\r
224         self.is_dead = 0;               //TEMP\r
225 \r
226         if ((self.team_no != 0))\r
227         {\r
228                 spot = FindTeamSpawnPoint (self.team_no);\r
229                 if ((spot != world))\r
230                 {\r
231                         return (spot);\r
232                 }\r
233         }\r
234         if (coop)\r
235         {\r
236                 lastspawn = find (lastspawn, classname, "info_player_coop");\r
237                 if ((lastspawn == world))\r
238                 {\r
239                         lastspawn = find (world, classname, "info_player_coop");\r
240                 }\r
241                 if ((lastspawn != world))\r
242                 {\r
243                         return (lastspawn);\r
244                 }\r
245         }\r
246         else\r
247         {\r
248                 if (deathmatch)\r
249                 {\r
250                         spot = find (lastspawn, classname, "info_player_deathmatch");\r
251                         if ((spot == world))\r
252                         {\r
253                                 spot = find (world, classname, "info_player_deathmatch");\r
254                         }\r
255                         attempts = 0;\r
256                         while (((spot != world) && (attempts < 100)))\r
257                         {\r
258                                 attempts = (attempts + 1);\r
259                                 at_spot = findradius (spot.origin, 40);\r
260                                 spot_found = 1;\r
261                                 while (at_spot)\r
262                                 {\r
263                                         if (((at_spot.classname == "player") && (at_spot.deadflag == 0)))\r
264                                         {\r
265                                                 spot_found = 0;\r
266                                         }\r
267                                         at_spot = at_spot.chain;\r
268                                 }\r
269                                 if ((spot_found || (attempts >= 10)))\r
270                                 {\r
271                                         lastspawn = spot;\r
272                                         return (spot);\r
273                                 }\r
274                                 spot = find (spot, classname, "info_player_deathmatch");\r
275                                 if ((spot == world))\r
276                                 {\r
277                                         spot = find (world, classname, "info_player_deathmatch");\r
278                                 }\r
279                         }\r
280                 }\r
281         }\r
282         if (serverflags)\r
283         {\r
284                 spot = find (world, classname, "info_player_start2");\r
285                 if (spot)\r
286                 {\r
287                         return (spot);\r
288                 }\r
289         }\r
290         spot = find (world, classname, "info_player_start");\r
291         /*if (!spot)\r
292         {\r
293                 spot = find (world, is_converted_goal, "yes");\r
294         }*/\r
295         spot = find(world, classname, "info_player_start");\r
296         if (!spot)\r
297         {\r
298                 spot = find (world, classname, "info_player_intermission");\r
299         }\r
300         if (!spot)\r
301         {\r
302 //              spot = find (world, classname, "info_tfgoal");\r
303         }\r
304         if (!spot)\r
305         {\r
306                 error ("PutClientInServer: no info_player_start on level\n");\r
307         }\r
308         return (spot);\r
309 };\r
310 \r
311 /*entity SelectSpawnPoint (void)                // Old, non-tf code\r
312 {\r
313         local entity spot, thing;\r
314         local float pcount;\r
315 \r
316         spot = find (world, classname, "testplayerstart");\r
317         if (spot)\r
318                 return spot;\r
319 \r
320         spot = lastspawn;\r
321         while (1)\r
322         {\r
323                 spot = find(spot, classname, "info_player_deathmatch");\r
324                 if (spot != world)\r
325                 {\r
326                         if (spot == lastspawn)\r
327                                 return lastspawn;\r
328                         pcount = 0;\r
329                         thing = findradius(spot.origin, 70);\r
330                         while(thing)\r
331                         {\r
332                                 if (thing.classname == "player")\r
333                                         pcount = pcount + 1;\r
334                                 thing = thing.chain;\r
335                         }\r
336                         if (pcount == 0)\r
337                         {\r
338                                 lastspawn = spot;\r
339                                 return spot;\r
340                         }\r
341                 }\r
342         }\r
343 \r
344         spot = find (world, classname, "info_player_start");\r
345         if (!spot)\r
346                 error ("PutClientInServer: no info_player_start on level");\r
347 \r
348         return spot;\r
349 }*/\r
350 \r
351 /*\r
352 =============\r
353 CheckPlayerModel\r
354 \r
355 Checks if the argument string can be a valid playermodel.\r
356 Returns a valid one in doubt.\r
357 =============\r
358 */\r
359 string CheckPlayerModel(string playermodel) {\r
360         if( substring(playermodel,0,13) != "models/class/") playermodel = "models/class/scout.zym";\r
361 \r
362         /* Possible Fixme: Check if server can open the model?\r
363            This would kill custom models, however. */\r
364 \r
365         return playermodel;\r
366 }\r
367 \r
368 \r
369 /*\r
370 =============\r
371 PutClientInServer\r
372 \r
373 Called when a client spawns in the server\r
374 =============\r
375 */\r
376 void PutClientInServer (void)\r
377 {\r
378         entity  spot;\r
379         float oldcl;\r
380         if (self.team_no < 1)\r
381         {\r
382         self.movetype = 0;\r
383         self.solid = 0;\r
384         self.flags = FL_CLIENT;\r
385         self.takedamage = DAMAGE_AIM;\r
386         self.effects = 0;\r
387         self.health = cvar("g_balance_health_start");\r
388         self.max_health = cvar("g_balance_health_stable");\r
389         self.armorvalue = cvar("g_balance_armor_start");\r
390         self.max_armor = self.armorvalue;\r
391         self.damageforcescale = 2;\r
392         self.death_time = 0;\r
393         self.dead_time = 0;\r
394         self.dead_frame = 0;\r
395         self.die_frame = 0;\r
396         self.alpha = 0;\r
397         self.scale = 0;\r
398         self.fade_time = 0;\r
399         self.pain_frame = 0;\r
400         self.pain_finished = 0;\r
401         self.strength_finished = 0;\r
402         self.invincible_finished = 0;\r
403         //self.speed_finished = 0;\r
404         //self.slowmo_finished = 0;\r
405         // players have no think function\r
406         self.think = SUB_Null;\r
407         self.nextthink = 0;\r
408         self.speed = -1;\r
409         self.jump_pad = 0;\r
410         spot = SelectSpawnPoint();\r
411 //      setorigin (self, spot.origin + '0 0 1' * (1 - self.mins_z + 24));\r
412 //      setorigin (self, spot.origin + '-2 0 4' * (1 - self.mins_z + 24));\r
413 //      self.angles_y = self.angles_y + 180;\r
414         return;\r
415         }\r
416         if (self.playerclass < 1)\r
417         {\r
418                 stuffcmd(self, "set scmenu_directmenu ClassSelect; togglemenu\n");\r
419                 return;\r
420         }\r
421 \r
422         // fixme: are these the right teams & colors?\r
423         /*if(self.team == 5)            // Wazat -- I'm using TeamFortress_TeamSet for this now\r
424         {\r
425                 self.team_no = 1;\r
426         }\r
427         if(self.team == 14)\r
428         {\r
429                 self.team_no = 2;\r
430         }\r
431         if(self.team == 4)\r
432         {\r
433                 self.team_no = 3;\r
434         }\r
435         if(self.team == 13)\r
436         {\r
437                 self.team_no = 4;\r
438         }*/\r
439 \r
440         DoTFAliases ();\r
441 \r
442 //      spot = SelectSpawnPoint ();             // moved down\r
443         self.classname = "player";\r
444         self.movetype = MOVETYPE_WALK;\r
445         self.solid = SOLID_SLIDEBOX;\r
446         self.flags = FL_CLIENT;\r
447         self.takedamage = DAMAGE_AIM;\r
448         self.effects = 0;\r
449         self.health = cvar("g_balance_health_start");\r
450         self.max_health = cvar("g_balance_health_stable");\r
451         self.armorvalue = cvar("g_balance_armor_start");\r
452         self.max_armor = self.armorvalue;\r
453         self.damageforcescale = 2;\r
454         self.death_time = 0;\r
455         self.dead_time = 0;\r
456         self.dead_frame = 0;\r
457         self.die_frame = 0;\r
458         self.alpha = 0;\r
459         self.scale = 0;\r
460         self.fade_time = 0;\r
461         self.pain_frame = 0;\r
462         self.pain_finished = 0;\r
463         self.strength_finished = 0;\r
464         self.invincible_finished = 0;\r
465         //self.speed_finished = 0;\r
466         //self.slowmo_finished = 0;\r
467         // players have no think function\r
468         self.think = SUB_Null;\r
469         self.nextthink = 0;\r
470         self.speed = -1;\r
471         self.jump_pad = 0;\r
472         //self.wpn5 = 0; // not carrying an extra weapon\r
473         ResetExtraWeapon(); // not carrying an extra weapon\r
474 \r
475         DelayHealthRegen(self);\r
476         DelayArmorRegen(self);\r
477         DelayHealthRot(self);\r
478         DelayArmorRot(self);\r
479 \r
480 \r
481         self.special_active = 0;\r
482         self.special_time = 0;\r
483 \r
484         self.grenade_time = 0;\r
485 \r
486         if(self.onfire != world)\r
487                 remove(self.onfire);\r
488         self.onfire = world;\r
489         self.flame_heat = 0;\r
490         self.flame_heat_time = 0;\r
491 \r
492         self.poison_damage = 0;\r
493         self.poison_rate = 0;\r
494 \r
495         self.is_feigning = 0;\r
496         self.current_menu = 0;\r
497 \r
498         // if the player is supposed to change model (and hence class) on respawn, do it.\r
499         if(self.change_mdl_on_respawn != "")\r
500         {\r
501                 self.playermodel = self.change_mdl_on_respawn;\r
502                 //strunzone(self.change_mdl_on_respawn); // can't unzone or it'll crash later\r
503         }\r
504         // set the class.  If he changed classes while dead it will take effect now.\r
505         oldcl = self.class;\r
506         self.class = GetPlayerClass();\r
507         Do_TFClass_Conversion();\r
508         ChangeClass((oldcl != self.class), FALSE);\r
509 \r
510 \r
511 \r
512         self.deadflag = DEAD_NO;\r
513 \r
514         spot = SelectSpawnPoint ();             // maybe temp\r
515         self.angles = spot.angles;\r
516         self.fixangle = TRUE; // turn this way immediately\r
517         self.velocity = '0 0 0';\r
518         self.avelocity = '0 0 0';\r
519         self.punchangle = '0 0 0';\r
520         self.punchvector = '0 0 0';\r
521 \r
522         self.viewzoom = 0.6;\r
523 \r
524 \r
525         self.playermodel = CheckPlayerModel(self.playermodel);\r
526 \r
527         precache_model (self.playermodel);\r
528         setmodel (self, self.playermodel);\r
529         self.skin = stof(self.playerskin);\r
530         self.mdl = strzone(self.playermodel);\r
531 \r
532         self.crouch = FALSE;\r
533         self.view_ofs = PL_VIEW_OFS;\r
534         setsize (self, PL_MIN, PL_MAX);\r
535         setorigin (self, spot.origin + '0 0 1' * (1 - self.mins_z - 24));\r
536         // don't reset back to last position, even if new position is stuck in solid\r
537         self.oldorigin = self.origin;\r
538 \r
539 //      self.items = IT_LASER | IT_UZI| IT_SHOTGUN | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER;\r
540 //      self.weapon = IT_UZI;\r
541 \r
542 \r
543         // fixme: move this to Become<Class> code\r
544 /*      self.items = IT_WEP1 | IT_WEP2 | IT_WEP3 | IT_WEP4;\r
545         //self.weapon = 1;\r
546         self.switchweapon = IT_WEP2;\r
547         self.ammo_shells = 50;\r
548         self.ammo_nails = 0;\r
549         self.ammo_rockets = 0;\r
550         self.ammo_cells = 0;*/\r
551 \r
552         if (cvar("g_fullbrightplayers") == 1)\r
553                 self.effects = EF_FULLBRIGHT;\r
554 \r
555         self.event_damage = PlayerDamage;\r
556 \r
557         self.statdraintime = time + 5;\r
558         self.button0 = self.button1 = self.button2 = self.button3 = 0;\r
559 \r
560         /*\r
561         W_UpdateWeapon();\r
562         W_UpdateAmmo();\r
563         */\r
564         CL_SpawnWeaponentity();\r
565         self.weaponentity.alpha = self.exteriorweaponentity.alpha = 0;\r
566         self.weaponentity.colormod = '0 0 0';\r
567         self.weaponentity.scale = 0;\r
568 \r
569         //stuffcmd(self, "chase_active 0");\r
570 }\r
571 \r
572 /*\r
573 =============\r
574 SetNewParms\r
575 =============\r
576 */\r
577 void SetNewParms (void)\r
578 {\r
579 \r
580 }\r
581 \r
582 /*\r
583 =============\r
584 SetChangeParms\r
585 =============\r
586 */\r
587 void SetChangeParms (void)\r
588 {\r
589 \r
590 }\r
591 \r
592 /*\r
593 =============\r
594 ClientKill\r
595 \r
596 Called when a client types 'kill' in the console\r
597 =============\r
598 */\r
599 void ClientKill (void)\r
600 {\r
601         Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');\r
602 }\r
603 \r
604 /*\r
605 =============\r
606 ClientConnect\r
607 \r
608 Called when a client connects to the server\r
609 =============\r
610 */\r
611 void ClientConnect (void)\r
612 {\r
613         //ClientInRankings();\r
614         bprint ("^4",self.netname);\r
615         bprint (" connected\n");\r
616         stuffcmd(self, strcat("exec maps/", mapname, ".cfg\n"));\r
617         // send prediction settings to the client\r
618         stuffcmd(self, strcat("cl_movement_maxspeed ", ftos(cvar("sv_maxspeed")), "\n"));\r
619         stuffcmd(self, strcat("cl_movement_maxairspeed ", ftos(cvar("sv_maxairspeed")), "\n"));\r
620         stuffcmd(self, strcat("cl_movement_accelerate ", ftos(cvar("sv_accelerate")), "\n"));\r
621         stuffcmd(self, strcat("cl_movement_friction ", ftos(cvar("sv_friction")), "\n"));\r
622         stuffcmd(self, strcat("cl_movement_stopspeed ", ftos(cvar("sv_stopspeed")), "\n"));\r
623         stuffcmd(self, strcat("cl_movement_jumpvelocity ", ftos(cvar("g_balance_jumpheight")), "\n"));\r
624         stuffcmd(self, strcat("cl_movement_stepheight ", ftos(cvar("sv_stepheight")), "\n"));\r
625         stuffcmd(self, strcat("cl_movement_edgefriction 0\n"));\r
626                         // TEMP FOR TESTING PURPOSES!\r
627         //teamplay = 21?TeamFortress;\r
628         DecodeLevelParms ();\r
629         //cvar_set ("teamplay", "21?TeamFortress");\r
630         //      teamplay = cvar ("teamplay");\r
631 \r
632 /*      joinorder = joinorder + 1;                      // old temp autoteam, but now we have a menu instead :P\r
633         if (joinorder == 1 || joinorder == 3 || joinorder == 5 || joinorder == 7)\r
634                 TeamFortress_TeamSet (1);\r
635         else {\r
636                 TeamFortress_TeamSet (2);\r
637         }*/\r
638 }\r
639 \r
640 /*\r
641 =============\r
642 ClientDisconnect\r
643 \r
644 Called when a client disconnects from the server\r
645 =============\r
646 */\r
647 .entity chatbubbleentity;\r
648 void ClientDisconnect (void)\r
649 {\r
650         //ClientDisconnected();\r
651         self.has_disconnected = 1;\r
652         bprint ("^4",self.netname);\r
653         bprint (" disconnected\n");\r
654 \r
655         if (self.chatbubbleentity)\r
656         {\r
657                 remove (self.chatbubbleentity);\r
658                 self.chatbubbleentity = world;\r
659         }\r
660         \r
661         if (self.teambubble_friendly)\r
662         {\r
663                 remove (self.teambubble_friendly);\r
664                 self.teambubble_friendly = world;\r
665         }\r
666         if (self.teambubble_needhealth)\r
667         {\r
668                 remove (self.teambubble_needhealth);\r
669                 self.teambubble_needhealth = world;\r
670         }\r
671 }\r
672 \r
673 .entity chatbubbleentity;\r
674 .float buttonchat;\r
675 void() ChatBubbleThink =\r
676 {\r
677         self.nextthink = time;\r
678         if (!self.owner.modelindex || self.owner.chatbubbleentity != self)\r
679         {\r
680                 remove(self);\r
681                 return;\r
682         }\r
683         setorigin(self, self.owner.origin + '0 0 15' + self.owner.maxs_z * '0 0 1');\r
684         if (self.owner.buttonchat)\r
685                 self.effects = 0;\r
686         else\r
687                 self.effects = EF_NODRAW;\r
688 };\r
689 \r
690 void() UpdateChatBubble =\r
691 {\r
692         if (!self.modelindex)\r
693                 return;\r
694         // spawn a chatbubble entity if needed\r
695         if (!self.chatbubbleentity)\r
696         {\r
697                 self.chatbubbleentity = spawn();\r
698                 self.chatbubbleentity.owner = self;\r
699                 self.chatbubbleentity.think = ChatBubbleThink;\r
700                 self.chatbubbleentity.nextthink = time;\r
701                 setmodel(self.chatbubbleentity, "models/misc/chatbubble.spr");\r
702                 setorigin(self.chatbubbleentity, self.origin + '0 0 15' + self.maxs_z * '0 0 1');\r
703                 self.chatbubbleentity.effects = EF_NODRAW;\r
704         }\r
705 }\r
706 \r
707 // LordHavoc: this hack will be removed when proper _pants/_shirt layers are\r
708 // added to the model skins\r
709 void() UpdateColorModHack =\r
710 {\r
711         local float c;\r
712         c = self.clientcolors & 15;\r
713         // LordHavoc: only bothering to support white, green, red, yellow, blue\r
714              if (teamplay == 0) self.colormod = '0 0 0';\r
715         else if (c ==  0) self.colormod = '1.00 1.00 1.00';\r
716         else if (c ==  3) self.colormod = '0.10 1.73 0.10';\r
717         else if (c ==  4) self.colormod = '1.73 0.10 0.10';\r
718         else if (c == 12) self.colormod = '1.22 1.22 0.10';\r
719         else if (c == 13) self.colormod = '0.10 0.10 1.73';\r
720         else self.colormod = '1 1 1';\r
721 };\r
722 \r
723 /*\r
724 =============\r
725 PlayerJump\r
726 \r
727 When you press the jump key\r
728 =============\r
729 */\r
730 void PlayerJump (void)\r
731 {\r
732         if (self.waterlevel >= 2)\r
733         {\r
734                 if (self.watertype == CONTENT_WATER)\r
735                         self.velocity_z = 200;\r
736                 else if (self.watertype == CONTENT_SLIME)\r
737                         self.velocity_z = 80;\r
738                 else\r
739                         self.velocity_z = 50;\r
740 \r
741                 return;\r
742         }\r
743         if(self.jump_pad)\r
744                 return;\r
745 \r
746 //      self.jump_pad = 0;\r
747         CapPlayerVelocity(self, self.speed);\r
748 \r
749 \r
750         if (!(self.flags & FL_ONGROUND))\r
751                 return;\r
752 \r
753         if (!(self.flags & FL_JUMPRELEASED))\r
754                 return;\r
755 \r
756         self.velocity_z = self.velocity_z + cvar("g_balance_jumpheight");\r
757 \r
758         self.flags = self.flags - FL_ONGROUND;\r
759         self.flags = self.flags - FL_JUMPRELEASED;\r
760 }\r
761 \r
762 .float watersound_finished;\r
763 void() WaterMove =\r
764 {\r
765         if (self.movetype == MOVETYPE_NOCLIP)\r
766                 return;\r
767         if (self.health < 0)\r
768                 return;\r
769 \r
770         if (self.waterlevel != 3)\r
771         {\r
772                 self.air_finished = time + 12;\r
773                 self.dmg = 2;\r
774         }\r
775         else if (self.air_finished < time)\r
776         {       // drown!\r
777                 if (self.pain_finished < time)\r
778                 {\r
779                         Damage (self, world, world, 5, DEATH_DROWN, self.origin, '0 0 0');\r
780                         self.pain_finished = time + 0.5;\r
781                 }\r
782         }\r
783 \r
784         if (!self.waterlevel)\r
785         {\r
786                 if (self.flags & FL_INWATER)\r
787                 {\r
788                         // play leave water sound\r
789                         self.flags = self.flags - FL_INWATER;\r
790                 }\r
791                 return;\r
792         }\r
793 \r
794         if (self.watersound_finished < time)\r
795         {\r
796                 self.watersound_finished = time + 0.5;\r
797                 if (self.watertype == CONTENT_LAVA)\r
798                         sound (self, CHAN_BODY, "player/lava.wav", 1, ATTN_NORM);\r
799                 if (self.watertype == CONTENT_SLIME)\r
800                         sound (self, CHAN_BODY, "player/slime.wav", 1, ATTN_NORM);\r
801                 //if (self.watertype == CONTENT_WATER)\r
802                 //      sound (self, CHAN_BODY, "player/water.wav", 1, ATTN_NORM);\r
803         }\r
804 \r
805         if (self.watertype == CONTENT_LAVA)\r
806         {       // do damage\r
807 \r
808                 // lava sets me to the maximum heat level, so I'll catch fire easily\r
809                 self.flame_heat = cvar("g_balance_maxheat");\r
810 \r
811                 if (self.dmgtime < time)\r
812                 {\r
813                         self.dmgtime = time + 0.1;\r
814                         Damage (self, world, world, 3 * self.waterlevel, DEATH_LAVA, self.origin, '0 0 0');\r
815                 }\r
816         }\r
817         else if (self.watertype == CONTENT_SLIME)\r
818         {       // do damage\r
819 \r
820                 // cool me off\r
821                 self.flame_heat = 0;\r
822 \r
823                 if (self.dmgtime < time)\r
824                 {\r
825                         self.dmgtime = time + 0.1;\r
826                         Damage (self, world, world, 1 * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');\r
827                 }\r
828         }\r
829         else if (self.watertype == CONTENT_WATER)\r
830         {\r
831                 // cool me off\r
832                 self.flame_heat = 0;\r
833         }\r
834 \r
835         if ( !(self.flags & FL_INWATER) )\r
836         {\r
837 \r
838                 //if (self.watertype == CONTENT_LAVA)\r
839                 //      sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);\r
840                 //if (self.watertype == CONTENT_WATER)\r
841                 //      sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);\r
842                 //if (self.watertype == CONTENT_SLIME)\r
843                 //      sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);\r
844 \r
845                 self.flags = self.flags + FL_INWATER;\r
846                 self.dmgtime = 0;\r
847         }\r
848 };\r
849 \r
850 void() CheckWaterJump =\r
851 {\r
852         local vector start, end;\r
853 \r
854 // check for a jump-out-of-water\r
855         makevectors (self.angles);\r
856         start = self.origin;\r
857         start_z = start_z + 8;\r
858         v_forward_z = 0;\r
859         normalize(v_forward);\r
860         end = start + v_forward*24;\r
861         traceline (start, end, TRUE, self);\r
862         if (trace_fraction < 1)\r
863         {       // solid at waist\r
864                 start_z = start_z + self.maxs_z - 8;\r
865                 end = start + v_forward*24;\r
866                 self.movedir = trace_plane_normal * -50;\r
867                 traceline (start, end, TRUE, self);\r
868                 if (trace_fraction == 1)\r
869                 {       // open at eye level\r
870                         self.flags = self.flags | FL_WATERJUMP;\r
871                         self.velocity_z = 225;\r
872                         self.flags = self.flags - (self.flags & FL_JUMPRELEASED);\r
873                         self.teleport_time = time + 2;  // safety net\r
874                         return;\r
875                 }\r
876         }\r
877 };\r
878 \r
879 \r
880 void respawn(void)\r
881 {\r
882         CopyBody(1);\r
883         PutClientInServer();\r
884 }\r
885 \r
886 void player_powerups (void)\r
887 {\r
888         self.effects = self.effects - (self.effects & (EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT));\r
889         if (self.items & IT_STRENGTH)\r
890         {\r
891                 self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);\r
892                 if (time > self.strength_finished)\r
893                 {\r
894                         self.items = self.items - (self.items & IT_STRENGTH);\r
895                         sprint(self, "^3Strength has worn off\n");\r
896                 }\r
897         }\r
898         else\r
899         {\r
900                 if (time < self.strength_finished)\r
901                 {\r
902                         self.items = self.items | IT_STRENGTH;\r
903                         sprint(self, "^3Strength infuses your weapons with devestating power\n");\r
904                 }\r
905         }\r
906         if (self.items & IT_INVINCIBLE)\r
907         {\r
908                 self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);\r
909                 if (time > self.invincible_finished)\r
910                 {\r
911                         self.items = self.items - (self.items & IT_INVINCIBLE);\r
912                         sprint(self, "^3Shield has worn off\n");\r
913                 }\r
914         }\r
915         else\r
916         {\r
917                 if (time < self.invincible_finished)\r
918                 {\r
919                         self.items = self.items | IT_INVINCIBLE;\r
920                         sprint(self, "^3Shield surrounds you\n");\r
921                 }\r
922         }\r
923 }\r
924 \r
925 void player_regen_health (float maxh, float regen_rate_mod)\r
926 {\r
927         if (self.health < maxh && time > self.health_regen_delay && self.health > 2)            // dont regen is HP is 2\r
928                 self.health = bound(0, self.health + regen_rate_mod*(maxh- self.health) * cvar("g_balance_health_regen") * frametime, 1000);\r
929 }\r
930 void player_rot_health (float maxh, float rot_rate_mod)\r
931 {\r
932         if (self.health > maxh && time > self.health_rot_delay)\r
933                 self.health = bound(0, self.health + rot_rate_mod*(maxh - self.health) * cvar("g_balance_health_rot") * frametime, 1000);\r
934 }\r
935 void player_regen_armor (float maxa, float regen_rate_mod)\r
936 {\r
937         if (self.armorvalue < maxa && time > self.armor_regen_delay)\r
938                 self.armorvalue = bound(0, self.armorvalue + regen_rate_mod*(maxa - self.armorvalue) * cvar("g_balance_armor_regen") * frametime, 1000);\r
939 }\r
940 void player_rot_armor (float maxa, float regen_rot_mod)\r
941 {\r
942         if (self.armorvalue > maxa && time > self.armor_rot_delay)\r
943                 self.armorvalue = bound(0, self.armorvalue + regen_rot_mod*(maxa - self.armorvalue) * cvar("g_balance_armor_rot") * frametime, 1000);\r
944 }\r
945 \r
946 void player_clearpoison(entity targ)\r
947 {\r
948         targ.poison_damage = targ.poison_rate = 0;\r
949 }\r
950 \r
951 void DelayHealthRegen(entity e) {       e.health_regen_delay = time + cvar("g_balance_regen_wait");}\r
952 void DelayHealthRot(entity e)   {       e.health_rot_delay = time + cvar("g_balance_rot_wait");}\r
953 void DelayArmorRegen(entity e)  {       e.armor_regen_delay = time + cvar("g_balance_regen_wait");}\r
954 void DelayArmorRot(entity e)    {       e.armor_rot_delay = time + cvar("g_balance_rot_wait");}\r
955 \r
956 \r
957 void player_takepoison()\r
958 {\r
959         float oldhealth, take;\r
960         if(self.health <= 5)\r
961         {\r
962                 player_clearpoison(self);\r
963                 return;\r
964         }\r
965         oldhealth = self.health;\r
966 \r
967         take = bound(0, self.poison_rate * frametime, self.health - 5);\r
968         if(take <= 0)\r
969         {\r
970                 player_clearpoison(self);\r
971                 return;\r
972         }\r
973 \r
974         DelayHealthRegen(self);\r
975         self.health = self.health - take;\r
976         self.poison_damage = self.poison_damage - take;\r
977 \r
978         if(self.health <= 5 || self.poison_damage <= 0)\r
979         {\r
980                 player_clearpoison(self);\r
981                 return;\r
982         }\r
983 }\r
984 \r
985 // cool off so you're not so vulnerable to fire\r
986 void player_cooloff ()\r
987 {\r
988         if(self.flame_heat_time > time)//heat up\r
989                 self.flame_heat = bound(0, self.flame_heat + self.flame_heat * cvar("g_balance_heatup_rate")  * frametime, cvar("g_balance_maxheat"));\r
990         else//cool off\r
991                 self.flame_heat = bound(0, self.flame_heat - self.flame_heat * cvar("g_balance_cooloff_rate") * frametime, cvar("g_balance_maxheat"));\r
992 }\r
993 \r
994 void player_regen (void)\r
995 {\r
996         local float maxh;\r
997         local float maxa;\r
998         maxh = self.max_health;//cvar("g_balance_health_stable");\r
999         maxa = self.max_armor;//cvar("g_balance_armor_stable");\r
1000 \r
1001         if(self.poison_damage)\r
1002         {\r
1003                 player_takepoison();\r
1004                 return;\r
1005         }\r
1006 \r
1007         if(self.class == CLASS_SPY)\r
1008         {// don't let spy regenerate if cloaked, but do allow rot if above max\r
1009                 if(self.special_active)\r
1010                 {\r
1011                         //if(self.health > maxh)\r
1012                                 player_rot_health(maxh, 1.0);\r
1013                         //if(self.armorvalue > maxa)\r
1014                                 player_rot_armor(maxa, 1.0);\r
1015                 }\r
1016                 else\r
1017                 {\r
1018                         player_regen_health(maxh, 0.1); // spies regenerate slowly, and mostly rely on health packs\r
1019                         player_regen_armor(maxa, 1.0);\r
1020                         player_rot_health(maxh, 1.0);\r
1021                         player_rot_armor(maxa, 1.0);\r
1022                 }\r
1023         }\r
1024         else\r
1025         {\r
1026                 player_regen_health(maxh, 1.0);\r
1027                 player_regen_armor(maxa, 1.0);\r
1028                 player_rot_health(maxh, 1.0);\r
1029                 player_rot_armor(maxa, 1.0);\r
1030         }\r
1031 \r
1032         player_cooloff();\r
1033 }\r
1034 \r
1035 /*\r
1036 =============\r
1037 PlayerPreThink\r
1038 \r
1039 Called every frame for each client before the physics are run\r
1040 =============\r
1041 */\r
1042 .float attack_finished;\r
1043 void PlayerPreThink (void)\r
1044 {\r
1045         local vector m1, m2;\r
1046 \r
1047         CheckRules_Player();\r
1048 \r
1049         if (intermission_running)\r
1050         {\r
1051                 IntermissionThink ();   // otherwise a button could be missed between\r
1052                 return;                                 // the think tics\r
1053         }\r
1054 \r
1055         if (self.deadflag != DEAD_NO)\r
1056         {\r
1057                 player_anim();\r
1058                 weapon_freeze();\r
1059                 if (self.deadflag == DEAD_DYING)\r
1060                 {\r
1061                         if (time > self.dead_time)\r
1062                                 self.deadflag = DEAD_DEAD;\r
1063                 }\r
1064                 else if (self.deadflag == DEAD_DEAD)\r
1065                 {\r
1066                         if (!self.button0 && !self.button2 && !self.button3)\r
1067                                 self.deadflag = DEAD_RESPAWNABLE;\r
1068                 }\r
1069                 else if (self.deadflag == DEAD_RESPAWNABLE)\r
1070                 {\r
1071                         if (self.button0 || self.button2 || self.button3  || self.button4)\r
1072                                 respawn();\r
1073                 }\r
1074                 return;\r
1075         }\r
1076 \r
1077         if (self.button5)\r
1078         {\r
1079                 if (!self.crouch)\r
1080                 {\r
1081                         self.crouch = TRUE;\r
1082                         self.view_ofs = PL_CROUCH_VIEW_OFS;\r
1083                         setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);\r
1084                 }\r
1085         }\r
1086         else\r
1087         {\r
1088                 if (self.crouch)\r
1089                 {\r
1090                         tracebox(self.origin, PL_MIN, PL_MAX, self.origin, FALSE, self);\r
1091                         if (!trace_startsolid)\r
1092                         {\r
1093                                 self.crouch = FALSE;\r
1094                                 self.view_ofs = PL_VIEW_OFS;\r
1095                                 setsize (self, PL_MIN, PL_MAX);\r
1096                         }\r
1097                 }\r
1098         }\r
1099 \r
1100         if (self.playermodel != self.mdl)\r
1101         {\r
1102                 //bprint("playermodel changed\n");\r
1103                 self.playermodel = CheckPlayerModel(self.playermodel);\r
1104                 if(CheckForClassChange()) // check if we'll allow it\r
1105                         return; // if there's a return value, drop what you're doing and let the player respawn\r
1106 \r
1107                 if(self.playermodel != self.mdl) // if change has been allowed\r
1108                 {\r
1109                         m1 = self.mins;\r
1110                         m2 = self.maxs;\r
1111                         precache_model (self.playermodel);\r
1112                         if(self.model != "")\r
1113                         {\r
1114                                 setmodel (self, self.playermodel);\r
1115                                 setsize (self, m1, m2);\r
1116                         }\r
1117                         self.mdl = strzone(self.playermodel);\r
1118                 }\r
1119         }\r
1120 \r
1121         ClassPreThink();\r
1122 \r
1123         if (self.skin != stof(self.playerskin))\r
1124                 self.skin = stof(self.playerskin);\r
1125 \r
1126         if(self.class == CLASS_SCOUT)\r
1127                 GrapplingHookFrame();\r
1128 \r
1129         W_WeaponFrame();\r
1130 \r
1131         if (self.button4 || (self.weapon == WEP_NEX && self.button3))\r
1132         {\r
1133                 if (self.viewzoom > 0.4)\r
1134                         self.viewzoom = max (0.4, self.viewzoom - frametime * 2);\r
1135         }\r
1136         else if (self.viewzoom < 1.0)\r
1137                 self.viewzoom = min (1.0, self.viewzoom + frametime);\r
1138 \r
1139 \r
1140         if (self.button2)\r
1141                 PlayerJump ();\r
1142         else\r
1143                 self.flags = self.flags | FL_JUMPRELEASED;\r
1144 \r
1145 \r
1146         player_powerups();\r
1147         player_regen();\r
1148         player_anim();\r
1149 \r
1150         //self.angles_y=self.v_angle_y + 90;   // temp\r
1151 \r
1152         WaterMove ();\r
1153         if (self.waterlevel == 2)\r
1154                 CheckWaterJump ();\r
1155 \r
1156         //if (TetrisPreFrame()) return;\r
1157 \r
1158         PlayerLasergatePreThink();\r
1159 }\r
1160 \r
1161 // Update weapon colors\r
1162 void UpdatePlayerColors () {\r
1163         if(self.weaponentity) {\r
1164                 self.weaponentity.colormap = self.colormap;\r
1165                 self.exteriorweaponentity.colormap = self.colormap;\r
1166         }\r
1167 }\r
1168 \r
1169 /*\r
1170 =============\r
1171 PlayerPostThink\r
1172 \r
1173 Called every frame for each client after the physics are run\r
1174 =============\r
1175 */\r
1176 void PlayerPostThink (void)\r
1177 {\r
1178         float soundrandom;\r
1179         CheckRules_Player();\r
1180         UpdateChatBubble();\r
1181         UpdateColorModHack();\r
1182         UpdateTeamBubble();\r
1183         UpdatePlayerColors();\r
1184         if (self.deadflag == DEAD_NO)\r
1185         if (self.impulse)\r
1186                 ImpulseCommands ();\r
1187         if (intermission_running)\r
1188                 return;         // intermission or finale\r
1189 \r
1190         // VorteX: landing on floor, landing damage etc.\r
1191         // LordHavoc: removed 'big fall' death code that VorteX added\r
1192         if (self.flags & FL_ONGROUND || (self.waterlevel >= 2 && self.velocity_z <= 0))\r
1193                         self.jump_pad = 0;\r
1194 \r
1195         if (self.flags & FL_ONGROUND)\r
1196         {\r
1197                 CapPlayerVelocity(self, self.speed);\r
1198 \r
1199                 if (self.jump_flag < -100 && !self.watertype == CONTENT_WATER) // HitGround\r
1200                 {\r
1201                         soundrandom = random() * 4;\r
1202 \r
1203                         self.air_time = time;           //temp BH var\r
1204 \r
1205                         if (soundrandom < 1)\r
1206                                 sound (self, CHAN_BODY, "misc/hitground1.wav", 1, ATTN_NORM);\r
1207                         else if (soundrandom < 2)\r
1208                                 sound (self, CHAN_BODY, "misc/hitground2.wav", 1, ATTN_NORM);\r
1209                         else if (soundrandom < 3)\r
1210                                 sound (self, CHAN_BODY, "misc/hitground3.wav", 1, ATTN_NORM);\r
1211                         else if (soundrandom < 4)\r
1212                                 sound (self, CHAN_BODY, "misc/hitground4.wav", 1, ATTN_NORM);\r
1213                         if (self.jump_flag < -650) // landing damage\r
1214                         {\r
1215                                 local float dm;\r
1216                                 dm = bound(0, 0.1*(fabs(self.jump_flag) - 600), 5);\r
1217                                 Damage (self, world, world, dm, DEATH_FALL, self.origin, '0 0 0');\r
1218                         }\r
1219                         self.jump_flag = 0;\r
1220                 }\r
1221         }\r
1222         else\r
1223                 self.jump_flag = self.velocity_z;\r
1224 \r
1225         ClassPostThink();\r
1226 \r
1227         //if (TetrisPostFrame()) return;\r
1228         PlayerLasergatePostThink();\r
1229 }\r
1230 \r
1231 // Parse team join, class etc.\r
1232 void SV_ParseClientCommand (string s)\r
1233 {\r
1234         local float args;\r
1235 //      local float h;\r
1236         local string c;\r
1237         local string d;\r
1238         local string f;\r
1239         local string g;\r
1240         local string i;\r
1241         args = tokenize(s);\r
1242         c = argv(0);\r
1243         d = argv(1);\r
1244         f = argv(2);\r
1245         g = argv(3);\r
1246         i = argv(4);\r
1247 \r
1248         if (c == "join")\r
1249     {\r
1250                 return;\r
1251         }\r
1252         if (c == "changeclass")\r
1253         {\r
1254                 stuffcmd(self, "set scmenu_directmenu ClassSelect; togglemenu\n");\r
1255                 return;\r
1256         }\r
1257         if (c == "selectteam")\r
1258     {\r
1259                 if (self.team_no > 0)\r
1260                 {\r
1261                         sprint(self, "You are already on a team!\n");\r
1262                         return;\r
1263                 }\r
1264                 if (d == "auto" || d == "5")\r
1265                 {\r
1266                         TeamFortress_TeamPutPlayerInTeam();\r
1267                         PutClientInServer ();\r
1268                 }\r
1269                 if (d == "blue" || d == "1")\r
1270                 {\r
1271                         TeamFortress_TeamSet (1);\r
1272                         PutClientInServer ();\r
1273                 }\r
1274                 if (d == "red" || d == "2")\r
1275                 {\r
1276                         TeamFortress_TeamSet (2);\r
1277                         PutClientInServer ();\r
1278                 }\r
1279                 if (d == "yellow" || d == "3")\r
1280                 {\r
1281                         TeamFortress_TeamSet (3);\r
1282                         PutClientInServer ();\r
1283                 }\r
1284                 if (d == "green" || d == "pink" || d == "4")            // Morphed set it to Pink in the menus. I think\r
1285                 {                                                                                                       // we should make it white instead.\r
1286                         TeamFortress_TeamSet (4);\r
1287                         PutClientInServer ();\r
1288                 }\r
1289                 return;\r
1290         }\r
1291         if (c == "selectclass")\r
1292     {\r
1293                 if (self.team_no < 1)\r
1294                 {\r
1295                         sprint(self, "You must select a team to join first!\n");\r
1296                         return;\r
1297                 }\r
1298                 if (TeamFortress_TeamIsCivilian (self.team_no))\r
1299                 {\r
1300                         self.impulse = 1;\r
1301                         TeamFortress_ChangeClass ();\r
1302                         return;\r
1303                 }\r
1304                 if (self.playerclass > 0)               // if a class is already chosen\r
1305                 {\r
1306                         self.tfstate = self.tfstate - (self.tfstate & 8);\r
1307                         local string cname;\r
1308                         if (d == ftos(TF_CLASS_SCOUT))\r
1309                         {\r
1310                                 cname = "scout";\r
1311                         }\r
1312                         if (d == ftos(TF_CLASS_SOLDIER))\r
1313                         {\r
1314                                 cname = "soldier";\r
1315                         }\r
1316                         if (d == ftos(TF_CLASS_MEDIC))\r
1317                         {\r
1318                                 cname = "medic";\r
1319                         }\r
1320                         if (d == ftos(TF_CLASS_PYRO))\r
1321                         {\r
1322                                 cname = "pyro";\r
1323                         }\r
1324                         if (d == ftos(TF_CLASS_ENGINEER))\r
1325                         {\r
1326                                 cname = "engineer";\r
1327                         }\r
1328                         if (d == ftos(TF_CLASS_SPY))\r
1329                         {\r
1330                                 cname = "spy";\r
1331                         }\r
1332                         if (d == ftos(TF_CLASS_RANDOM))\r
1333                         {\r
1334                                 self.tfstate = self.tfstate | 8;\r
1335                                 sprint(self, "You will respawn as a random class.\n");\r
1336                         }\r
1337                         if (cname != "")\r
1338                         {\r
1339 //                              stuffcmd(self, "_cl_playermodel \"models/class/");\r
1340 //                              stuffcmd(self, cname);\r
1341 //                              stuffcmd(self, "_mechanical.zym\"\n");\r
1342                                 if (cname == "engineer")\r
1343                                 {\r
1344                                         self.playermodel = strcat("models/class/",cname,"_other.zym");\r
1345                                 }\r
1346                                 else\r
1347                                 {\r
1348                                         self.playermodel = strcat("models/class/",cname,"_mechanical.zym");\r
1349                                 }\r
1350                                 if (self.is_dead == 1)          // if player is dead, can change class\r
1351                                         CheckForClassChange();\r
1352                         }\r
1353                 }\r
1354                 else                    // if no class is chosen\r
1355                 {\r
1356                         if (d == ftos(TF_CLASS_SCOUT))\r
1357                         {\r
1358                                 self.impulse = TF_CLASS_SCOUT;\r
1359                         }\r
1360                         if (d == ftos(TF_CLASS_SOLDIER))\r
1361                         {\r
1362                                 self.impulse = TF_CLASS_SOLDIER;\r
1363                         }\r
1364                         if (d == ftos(TF_CLASS_MEDIC))\r
1365                         {\r
1366                                 self.impulse = TF_CLASS_MEDIC;\r
1367                         }\r
1368                         if (d == ftos(TF_CLASS_PYRO))\r
1369                         {\r
1370                                 self.impulse = TF_CLASS_PYRO;\r
1371                         }\r
1372                         if (d == ftos(TF_CLASS_ENGINEER))\r
1373                         {\r
1374                                 self.impulse = TF_CLASS_ENGINEER;\r
1375                         }\r
1376                         if (d == ftos(TF_CLASS_SPY))\r
1377                         {\r
1378                                 self.impulse = TF_CLASS_SPY;\r
1379                         }\r
1380                         if (d == ftos(TF_CLASS_RANDOM))\r
1381                         {\r
1382                                 self.impulse = TF_CLASS_RANDOM;\r
1383                         }\r
1384                         TeamFortress_ChangeClass();\r
1385                 }\r
1386                 return;\r
1387         }\r
1388         else if (c == "check_val")\r
1389         {\r
1390                 if (d == "r_bloom")\r
1391                 {\r
1392                         if (f == "1")\r
1393                                 self.uses_bloom = 1;\r
1394                         else\r
1395                                 self.uses_bloom = 0;\r
1396                 }\r
1397         }\r
1398         else\r
1399         {\r
1400                 clientcommand(self, s);\r
1401         }\r
1402 };