]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/cl_impulse.qc
vehicles server & client code, disabled by default. see vehicles/vehicles.qh
[divverent/nexuiz.git] / data / qcsrc / server / cl_impulse.qc
1 .vector personal_v_angle; // view angles to restore on impulse 77
2 .vector personal_velocity; // velocity to restore on impulse 77
3
4 void CopyBody(float keepvelocity);
5
6 // changes by LordHavoc on 03/30/04
7 // cleaned up dummy code
8 // dummies are now removed eventually after being gibbed (norespawn = TRUE)
9 // dummy impulse now checks sv_cheats to prevent players from overwhelming server with dummies
10 // dummies now use player code where possible
11
12 void player_anim (void);
13 void DummyThink(void)
14 {
15         self.think = DummyThink;
16         self.nextthink = time;
17         SV_PlayerPhysics();
18         PlayerPreThink();
19         //player_anim();
20         PlayerPostThink();
21 }
22
23 // from dpmod
24 void printsurfaceinfo(entity e, vector v)
25 {
26         local float surfnum, numpoints, vnum;
27         local string s;
28         local vector n;
29         surfnum = getsurfacenearpoint(e, v);
30         if (surfnum >= 0)
31         {
32                 sprint(self, "texture: ");
33                 s = getsurfacetexture(e, surfnum);
34                 sprint(self, s);
35                 sprint(self, " normal: ");
36                 n = getsurfacenormal(e, surfnum);
37                 sprint(self, vtos(n));
38                 sprint(self, " ");
39                 numpoints = getsurfacenumpoints(e, surfnum);
40                 sprint(self, ftos(numpoints));
41                 sprint(self, " verts:");
42                 vnum = 0;
43                 while (vnum < numpoints)
44                 {
45                         sprint(self, " ");
46                         n = getsurfacepoint(e, surfnum, vnum);
47                         sprint(self, vtos(n));
48                         vnum = vnum + 1;
49                 }
50                 sprint(self, " point tested: ");
51                 sprint(self, vtos(v));
52                 sprint(self, " nearest point on surface: ");
53                 n = getsurfaceclippedpoint(e, surfnum, v);
54                 sprint(self, vtos(n));
55                 sprint(self, "\n");
56         }
57 };
58
59 /*
60  * Impulse map:
61  *
62  * 0 reserved (no input)
63  * 1 to 9, 14: weapon shortcuts
64  * 10: next weapon according to linear list
65  * 11: most recently used weapon
66  * 12: previous weapon according to linear list
67  * 13: best weapon according to priority list
68  * 15: next weapon according to priority list
69  * 16: previous weapon according to priority list
70  * 17: throw weapon
71  * 18: next weapon according to sbar_hudselector 1 list
72  * 19: previous weapon according to sbar_hudselector 1 list
73  * 20: reload if needed
74  *
75  * 30 to 39: create waypoints
76  * 47: clear personal waypoints
77  * 48: clear team waypoints
78  *
79  * 99: loaded
80  *
81  * 140: moving clone
82  * 141: ctf speedrun
83  * 142: fixed clone
84  * 143: emergency teleport
85  * 144: printsurfaceinfo
86  * 145: distance
87  * 148: unfairly eliminate
88  *
89  * TODO:
90  * 200 to 209: prev weapon shortcuts
91  * 210 to 219: best weapon shortcuts
92  * 220 to 229: next weapon shortcuts
93  * 230 to 253: individual weapons (up to 24)
94  */
95 void spawnfunc_racer();
96 //void spawnfunc_hov();
97 //void spawnfunc_vehicle_hoover();
98
99 void ImpulseCommands (void)
100 {
101         local float imp;
102         vector org;
103         float i;
104         float m;
105         float wep;
106         entity e, e2;
107
108         imp = self.impulse;
109         if (!imp || gameover)
110                 return;
111         self.impulse = 0;
112
113         if (timeoutStatus == 2) //don't allow any impulses while the game is paused
114                 return;
115
116
117
118     if(imp >= 21 && imp <= 29)
119     {
120                 entity r,os;
121
122         switch(imp)
123         {
124             case 21:
125                 os = self;
126                 r = spawn();
127                 self = r;
128                 setorigin(r,os.origin + v_forward * 256);
129                 spawnfunc_racer();
130                 self = os;
131                 return;
132             /*
133             case 22:
134                 os = self;
135                 r = spawn();
136                 self = r;
137                 setorigin(r,os.origin + v_forward * 256);
138                 spawnfunc_hov();
139                 self = os;
140                 return;
141             case 23:
142                 os = self;
143                 r = spawn();
144                 self = r;
145                 setorigin(r,os.origin + v_forward * 256);
146                 spawnfunc_vehicle_hoover();
147                 self = os;
148                 return;
149             */
150         }
151     }
152
153         if (imp >= 1 && imp <= 9)
154         {
155                 // weapon switching impulses
156                 if(self.deadflag == DEAD_NO)
157                         W_NextWeaponOnImpulse(imp);
158                 else
159                         self.impulse = imp; // retry in next frame
160         }
161         else if(imp >= 10 && imp <= 20)
162         {
163                 if(self.deadflag == DEAD_NO)
164                 {
165                         switch(imp)
166                         {
167                                 case 10:
168                                         W_NextWeapon (0);
169                                         break;
170                                 case 11:
171                                         W_SwitchWeapon (self.cnt); // previously used
172                                         break;
173                                 case 12:
174                                         W_PreviousWeapon (0);
175                                         break;
176                                 case 13:
177                                         W_SwitchWeapon (w_getbestweapon(self));
178                                         break;
179                                 case 14:
180                                         W_NextWeaponOnImpulse(0);
181                                         break;
182                                 case 15:
183                                         W_NextWeapon (2);
184                                         break;
185                                 case 16:
186                                         W_PreviousWeapon (2);
187                                         break;
188                                 case 17:
189                                         if (!g_minstagib)
190                                                 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
191                                         break;
192                                 case 18:
193                                         W_NextWeapon (1);
194                                         break;
195                                 case 19:
196                                         W_PreviousWeapon (1);
197                                         break;
198                                 case 20:
199                                         W_Reload ();
200                                         break;
201                         }
202                 }
203                 else
204                         self.impulse = imp; // retry in next frame
205         }
206         else if(imp >= 200 && imp <= 229)
207         {
208                 if(self.deadflag == DEAD_NO)
209                 {
210                         // custom order weapon cycling
211                         i = mod(imp, 10);
212                         m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next
213                         W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m);
214                 }
215                 else
216                         self.impulse = imp; // retry in next frame
217         }
218         else if(imp >= 230 && imp <= 253)
219         {
220                 if(self.deadflag == DEAD_NO)
221                         W_SwitchWeapon (imp - 230 + WEP_FIRST);
222                 else
223                         self.impulse = imp; // retry in next frame
224         }
225         // deploy waypoints
226         else if (imp >= 30 && imp <= 49)
227         {
228                 entity wp;
229                 switch(imp)
230                 {
231                         case 30:
232                                 wp = WaypointSprite_DeployPersonal("waypoint", self.origin);
233                                 if(wp)
234                                 {
235                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
236                                         WaypointSprite_Ping(wp);
237                                 }
238                                 self.personal_v_angle = self.v_angle;
239                                 self.personal_velocity = self.velocity;
240                                 sprint(self, "personal waypoint spawned at location\n");
241                                 break;
242                         case 31:
243                                 wp = WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
244                                 if(wp)
245                                 {
246                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
247                                         WaypointSprite_Ping(wp);
248                                 }
249                                 self.personal_v_angle = self.v_angle;
250                                 self.personal_velocity = '0 0 0';
251                                 sprint(self, "personal waypoint spawned at crosshair\n");
252                                 break;
253                         case 32:
254                                 if(vlen(self.death_origin))
255                                 {
256                                         wp = WaypointSprite_DeployPersonal("waypoint", self.death_origin);
257                                         if(wp)
258                                         {
259                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
260                                                 WaypointSprite_Ping(wp);
261                                         }
262                                         self.personal_v_angle = self.v_angle;
263                                         self.personal_velocity = '0 0 0';
264                                         sprint(self, "personal waypoint spawned at death location\n");
265                                 }
266                                 break;
267                         case 33:
268                                 if(self.deadflag == DEAD_NO && teams_matter)
269                                 {
270                                         wp = WaypointSprite_Attach("helpme", TRUE);
271                                         if(wp)
272                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_HELPME, '1 0.5 0'); // TODO choose better color
273                                         if(!wp)
274                                                 wp = self.waypointsprite_attachedforcarrier; // flag sprite?
275                                         if(wp)
276                                                 WaypointSprite_Ping(wp);
277                                         sprint(self, "HELP ME attached\n");
278                                 }
279                                 break;
280                         case 34:
281                                 wp = WaypointSprite_DeployFixed("here", FALSE, self.origin);
282                                 if(wp)
283                                 {
284                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
285                                         WaypointSprite_Ping(wp);
286                                 }
287                                 sprint(self, "HERE spawned at location\n");
288                                 break;
289                         case 35:
290                                 wp = WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
291                                 if(wp)
292                                 {
293                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
294                                         WaypointSprite_Ping(wp);
295                                 }
296                                 sprint(self, "HERE spawned at crosshair\n");
297                                 break;
298                         case 36:
299                                 if(vlen(self.death_origin))
300                                 {
301                                         wp = WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
302                                         if(wp)
303                                         {
304                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
305                                                 WaypointSprite_Ping(wp);
306                                         }
307                                         sprint(self, "HERE spawned at death location\n");
308                                 }
309                                 break;
310                         case 37:
311                                 wp = WaypointSprite_DeployFixed("danger", FALSE, self.origin);
312                                 if(wp)
313                                 {
314                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
315                                         WaypointSprite_Ping(wp);
316                                 }
317                                 sprint(self, "DANGER spawned at location\n");
318                                 break;
319                         case 38:
320                                 wp = WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
321                                 if(wp)
322                                 {
323                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
324                                         WaypointSprite_Ping(wp);
325                                 }
326                                 sprint(self, "DANGER spawned at crosshair\n");
327                                 break;
328                         case 39:
329                                 if(vlen(self.death_origin))
330                                 {
331                                         wp = WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
332                                         if(wp)
333                                         {
334                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
335                                                 WaypointSprite_Ping(wp);
336                                         }
337                                         sprint(self, "DANGER spawned at death location\n");
338                                 }
339                                 break;
340                         case 47:
341                                 WaypointSprite_ClearPersonal();
342                                 sprint(self, "personal waypoint cleared\n");
343                                 break;
344                         case 48:
345                                 WaypointSprite_ClearOwned();
346                                 sprint(self, "all waypoints cleared\n");
347                                 break;
348                 }
349         }
350         else if(imp >= 140 && imp <= 149 || imp == 99) // 10 cheats ought to be enough for anyone
351         {
352                 if(self.deadflag == DEAD_NO)
353                 {
354                         if(sv_cheats || (self.lip < sv_clones))
355                         {
356                                 switch(imp)
357                                 {
358                                          case 140:
359                                                 makevectors (self.v_angle);
360                                                 self.velocity = self.velocity + v_forward * 300;
361                                                 CopyBody(1);
362                                                 self.lip += 1;
363                                                 self.velocity = self.velocity - v_forward * 300;
364                                                 break;
365                                         case 142:
366                                                 CopyBody(0);
367                                                 self.lip += 1;
368                                                 break;
369                                  }
370                         }
371
372                         if(sv_cheats)
373                         {
374                                 switch(imp)
375                                 {
376                                         case 99:
377                                                 self.weapons |= WEPBIT_ALL;
378                                                 self.items |= IT_UNLIMITED_AMMO;
379                                                 self.ammo_shells = g_pickup_shells_max;
380                                                 self.ammo_nails = g_pickup_nails_max;
381                                                 self.ammo_rockets = g_pickup_rockets_max;
382                                                 self.ammo_cells = g_pickup_cells_max;
383                                                 self.ammo_fuel = g_pickup_fuel_max;
384                                                 self.health = g_pickup_healthsmall_max;
385                                                 self.armorvalue = g_pickup_armorsmall_max;
386                                                 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
387                                                 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
388                                                 self.pauserotfuel_finished = time + cvar("g_balance_pause_fuel_rot_spawn");
389                                                 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
390                                                 // precache weapon models/sounds
391                                                 wep = WEP_FIRST;
392                                                 while (wep <= WEP_LAST)
393                                                 {
394                                                         weapon_action(wep, WR_PRECACHE);
395                                                         wep = wep + 1;
396                                                 }
397                                                 break;
398                                         case 141:
399                                                 if(self.waypointsprite_deployed_personal)
400                                                 {
401                                                         self.speedrunning = TRUE;
402                                                         tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
403                                                         if(trace_startsolid)
404                                                         {
405                                                                 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
406                                                         }
407                                                         else
408                                                         {
409                                                                 // Abort speedrun, teleport back
410                                                                 setorigin(self, self.waypointsprite_deployed_personal.origin);
411                                                                 self.oldvelocity = self.velocity = self.personal_velocity;
412                                                                 self.angles = self.personal_v_angle;
413                                                                 self.fixangle = TRUE;
414                                                                 if(self.flagcarried)
415                                                                 {
416                                                                         bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
417                                                                         ReturnFlag(self.flagcarried);
418                                                                 }
419                                                         }
420                                                         self.ammo_rockets = 999;
421                                                         self.ammo_nails = 999;
422                                                         self.ammo_cells = 999;
423                                                         self.ammo_shells = 999;
424                                                         self.ammo_fuel = 999;
425                                                         self.health = start_health;
426                                                         self.armorvalue = start_armorvalue;
427                                                         self.weapons |= weaponsInMap;
428                                                         self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
429                                                         self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
430                                                         self.pauserotfuel_finished = time + cvar("g_balance_pause_fuel_rot_spawn");
431                                                         self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
432                                                 }
433                                                 else if(self.deadflag != DEAD_NO)
434                                                         sprint(self, "UR DEAD AHAHAH))\n");
435                                                 else
436                                                         sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
437                                                 break;
438                                         case 143:
439                                                 if(MoveToRandomMapLocation(self, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, ((sv_cheats >= 2) ? 100000 : 100), 1024, 256))
440                                                 {
441                                                         self.angles_x = -self.angles_x;
442                                                         self.fixangle = TRUE;
443                                                         self.velocity = '0 0 0';
444                                                 }
445                                                 else
446                                                         sprint(self, "Emergency teleport could not find a good location, forget it!\n");
447                                                 break;
448                                         case 144:
449                                                 makevectors(self.v_angle);
450                                                 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
451                                                 if (trace_fraction < 1)
452                                                         printsurfaceinfo(trace_ent, trace_endpos);
453                                                 break;
454                                         case 145:
455                                                 makevectors(self.v_angle);
456                                                 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
457                                                 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
458                                                 break;
459                                         case 146:
460                                                 makevectors(self.v_angle);
461                                                 i = self.dphitcontentsmask;
462                                                 self.dphitcontentsmask = DPCONTENTS_OPAQUE;
463                                                 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
464                                                 self.dphitcontentsmask = i;
465                                                 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
466                                                 pointparticles(particleeffectnum("fire_big"), trace_endpos, '0 0 0', 10);
467                                                 break;
468                                         case 148:
469                                                 FOR_EACH_PLAYER(e)
470                                                 {
471                                                         if( e.playermodel == "models/player/jeandarc.zym"
472                                                         ||  e.playermodel == "models/player/pyria.zym"
473                                                         ||  e.playermodel == "models/player/skadi.zym"
474                                                         || (e.playermodel == "models/player/specop.zym" && random() < 0.5) // you never know
475                                                         ||  e.playermodel == "models/player/visitant.zym")
476                                                         {
477                                                                 makevectors(e.angles);
478                                                                 traceline(e.origin, e.origin + v_right * 256, MOVE_NORMAL, e);
479                                                         }
480                                                         else
481                                                         {
482                                                                 org_x = random();
483                                                                 org_y = random();
484                                                                 org_z = 0;
485                                                                 org = normalize(org);
486                                                                 traceline(e.origin, e.origin + org * 256, MOVE_NORMAL, e); // random direction
487                                                         }
488
489                                                         org = findbetterlocation(trace_endpos, 12);
490
491                                                         e2 = spawn();
492                                                         setorigin(e2, org);
493                                                         pointparticles(particleeffectnum("rocket_explode"), org, '0 0 0', 1);
494                                                         sound(e2, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
495                                                         RadiusDamage(e2, e, 1000, 0, 128, e, 500, DEATH_CHEAT, world);
496                                                         remove(e2);
497                                                 }
498                                                 print("404 Sportsmanship not found.\n");
499                                                 break;
500                                 }
501                         }
502                 }
503         }
504         else if(imp >= 103 && imp <= 106)
505         {
506                 if(cvar("g_waypointeditor"))
507                 {
508                         switch(imp)
509                         {
510                                 case 103:
511                                         waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
512                                         bprint(strcat("Waypoint spawned at ",vtos(self.origin),"\n"));
513                                         break;
514                                 case 104:
515                                         e = navigation_findnearestwaypoint(self, FALSE);
516                                         if (e)
517                                         if not(e.wpflags & WAYPOINTFLAG_GENERATED)
518                                         {
519                                                 bprint(strcat("Waypoint removed at ",vtos(e.origin),"\n"));
520                                                 waypoint_remove(e);
521                                         }
522                                         break;
523                                 case 105:
524                                         waypoint_schedulerelinkall();
525                                         break;
526                                 case 106:
527                                         waypoint_saveall();
528                                         break;
529                         }
530                 }
531         }
532
533         //TetrisImpulses(imp);
534 }