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