]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/cl_impulse.qc
factor out impulse 911 into a function MoveToRandomMapLocation
[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  *
88  * TODO:
89  * 200 to 209: prev weapon shortcuts
90  * 210 to 219: best weapon shortcuts
91  * 220 to 229: next weapon shortcuts
92  * 230 to 253: individual weapons (up to 24)
93  */
94
95 void ImpulseCommands (void)
96 {
97         local float imp;
98         float i;
99         float m;
100         float wep;
101         entity e;
102
103         imp = self.impulse;
104         if (!imp || gameover)
105                 return;
106         self.impulse = 0;
107
108         if (timeoutStatus == 2) //don't allow any impulses while the game is paused
109                 return;
110
111         if (imp >= 1 && imp <= 9)
112         {
113                 // weapon switching impulses
114                 if(self.deadflag == DEAD_NO)
115                         W_NextWeaponOnImpulse(imp);
116                 else
117                         self.impulse = imp; // retry in next frame
118         }
119         else if(imp >= 10 && imp <= 20)
120         {
121                 if(self.deadflag == DEAD_NO)
122                 {
123                         switch(imp)
124                         {
125                                 case 10:
126                                         W_NextWeapon (0);
127                                         break;
128                                 case 11:
129                                         W_SwitchWeapon (self.cnt); // previously used
130                                         break;
131                                 case 12:
132                                         W_PreviousWeapon (0);
133                                         break;
134                                 case 13:
135                                         W_SwitchWeapon (w_getbestweapon(self));
136                                         break;
137                                 case 14:
138                                         W_NextWeaponOnImpulse(0);
139                                         break;
140                                 case 15:
141                                         W_NextWeapon (2);
142                                         break;
143                                 case 16:
144                                         W_PreviousWeapon (2);
145                                         break;
146                                 case 17:
147                                         if (!g_minstagib)
148                                                 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
149                                         break;
150                                 case 18:
151                                         W_NextWeapon (1);
152                                         break;
153                                 case 19:
154                                         W_PreviousWeapon (1);
155                                         break;
156                                 case 20:
157                                         W_Reload ();
158                                         break;
159                         }
160                 }
161                 else
162                         self.impulse = imp; // retry in next frame
163         }
164         else if(imp >= 200 && imp <= 229)
165         {
166                 if(self.deadflag == DEAD_NO)
167                 {
168                         // custom order weapon cycling
169                         i = mod(imp, 10);
170                         m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next
171                         W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m);
172                 }
173                 else
174                         self.impulse = imp; // retry in next frame
175         }
176         else if(imp >= 230 && imp <= 253)
177         {
178                 if(self.deadflag == DEAD_NO)
179                         W_SwitchWeapon (imp - 230 + WEP_FIRST);
180                 else
181                         self.impulse = imp; // retry in next frame
182         }
183         // deploy waypoints
184         else if (imp >= 30 && imp <= 49)
185         {
186                 entity wp;
187                 switch(imp)
188                 {
189                         case 30:
190                                 wp = WaypointSprite_DeployPersonal("waypoint", self.origin);
191                                 if(wp)
192                                 {
193                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
194                                         WaypointSprite_Ping(wp);
195                                 }
196                                 self.personal_v_angle = self.v_angle;
197                                 self.personal_velocity = self.velocity;
198                                 sprint(self, "personal waypoint spawned at location\n");
199                                 break;
200                         case 31:
201                                 wp = WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
202                                 if(wp)
203                                 {
204                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
205                                         WaypointSprite_Ping(wp);
206                                 }
207                                 self.personal_v_angle = self.v_angle;
208                                 self.personal_velocity = '0 0 0';
209                                 sprint(self, "personal waypoint spawned at crosshair\n");
210                                 break;
211                         case 32:
212                                 if(vlen(self.death_origin))
213                                 {
214                                         wp = WaypointSprite_DeployPersonal("waypoint", self.death_origin);
215                                         if(wp)
216                                         {
217                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_WAYPOINT, '0 1 1');
218                                                 WaypointSprite_Ping(wp);
219                                         }
220                                         self.personal_v_angle = self.v_angle;
221                                         self.personal_velocity = '0 0 0';
222                                         sprint(self, "personal waypoint spawned at death location\n");
223                                 }
224                                 break;
225                         case 33:
226                                 if(self.deadflag == DEAD_NO && teams_matter)
227                                 {
228                                         wp = WaypointSprite_Attach("helpme", TRUE);
229                                         if(wp)
230                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_HELPME, '1 0.5 0'); // TODO choose better color
231                                         if(!wp)
232                                                 wp = self.waypointsprite_attachedforcarrier; // flag sprite?
233                                         if(wp)
234                                                 WaypointSprite_Ping(wp);
235                                         sprint(self, "HELP ME attached\n");
236                                 }
237                                 break;
238                         case 34:
239                                 wp = WaypointSprite_DeployFixed("here", FALSE, self.origin);
240                                 if(wp)
241                                 {
242                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
243                                         WaypointSprite_Ping(wp);
244                                 }
245                                 sprint(self, "HERE spawned at location\n");
246                                 break;
247                         case 35:
248                                 wp = WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
249                                 if(wp)
250                                 {
251                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
252                                         WaypointSprite_Ping(wp);
253                                 }
254                                 sprint(self, "HERE spawned at crosshair\n");
255                                 break;
256                         case 36:
257                                 if(vlen(self.death_origin))
258                                 {
259                                         wp = WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
260                                         if(wp)
261                                         {
262                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_HERE, '0 1 0');
263                                                 WaypointSprite_Ping(wp);
264                                         }
265                                         sprint(self, "HERE spawned at death location\n");
266                                 }
267                                 break;
268                         case 37:
269                                 wp = WaypointSprite_DeployFixed("danger", FALSE, self.origin);
270                                 if(wp)
271                                 {
272                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
273                                         WaypointSprite_Ping(wp);
274                                 }
275                                 sprint(self, "DANGER spawned at location\n");
276                                 break;
277                         case 38:
278                                 wp = WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
279                                 if(wp)
280                                 {
281                                         WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
282                                         WaypointSprite_Ping(wp);
283                                 }
284                                 sprint(self, "DANGER spawned at crosshair\n");
285                                 break;
286                         case 39:
287                                 if(vlen(self.death_origin))
288                                 {
289                                         wp = WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
290                                         if(wp)
291                                         {
292                                                 WaypointSprite_UpdateTeamRadar(wp, RADARICON_DANGER, '1 0.5 0');
293                                                 WaypointSprite_Ping(wp);
294                                         }
295                                         sprint(self, "DANGER spawned at death location\n");
296                                 }
297                                 break;
298                         case 47:
299                                 WaypointSprite_ClearPersonal();
300                                 sprint(self, "personal waypoint cleared\n");
301                                 break;
302                         case 48:
303                                 WaypointSprite_ClearOwned();
304                                 sprint(self, "all waypoints cleared\n");
305                                 break;
306                 }
307         }
308         else if(imp >= 140 && imp <= 149 || imp == 99) // 10 cheats ought to be enough for anyone
309         {
310                 if(self.deadflag == DEAD_NO)
311                 {
312                         if(sv_cheats || (self.lip < sv_clones))
313                         {
314                                 switch(imp)
315                                 {       
316                                          case 140:
317                                                 makevectors (self.v_angle);
318                                                 self.velocity = self.velocity + v_forward * 300;
319                                                 CopyBody(1);
320                                                 self.lip += 1;
321                                                 self.velocity = self.velocity - v_forward * 300;
322                                                 break;
323                                         case 142:
324                                                 CopyBody(0);
325                                                 self.lip += 1;
326                                                 break;
327                                  }
328                         }
329
330                         if(sv_cheats)
331                         {
332                                 switch(imp)
333                                 {
334                                         case 99:
335                                                 self.weapons |= WEPBIT_ALL;
336                                                 self.items |= IT_UNLIMITED_AMMO;
337                                                 self.ammo_shells = g_pickup_shells_max;
338                                                 self.ammo_nails = g_pickup_nails_max;
339                                                 self.ammo_rockets = g_pickup_rockets_max;
340                                                 self.ammo_cells = g_pickup_cells_max;
341                                                 self.health = g_pickup_healthsmall_max;
342                                                 self.armorvalue = g_pickup_armorsmall_max;
343                                                 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
344                                                 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
345                                                 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
346                                                 // precache weapon models/sounds
347                                                 wep = WEP_FIRST;
348                                                 while (wep <= WEP_LAST)
349                                                 {
350                                                         weapon_action(wep, WR_PRECACHE);
351                                                         wep = wep + 1;
352                                                 }
353                                                 break;
354                                         case 141:
355                                                 if(self.waypointsprite_deployed_personal)
356                                                 {
357                                                         self.speedrunning = TRUE;
358                                                         tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
359                                                         if(trace_startsolid)
360                                                         {
361                                                                 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
362                                                         }
363                                                         else
364                                                         {
365                                                                 // Abort speedrun, teleport back
366                                                                 setorigin(self, self.waypointsprite_deployed_personal.origin);
367                                                                 self.oldvelocity = self.velocity = self.personal_velocity;
368                                                                 self.angles = self.personal_v_angle;
369                                                                 self.fixangle = TRUE;
370                                                                 if(self.flagcarried)
371                                                                 {
372                                                                         bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
373                                                                         ReturnFlag(self.flagcarried);
374                                                                 }
375                                                         }
376                                                         self.ammo_rockets = 999;
377                                                         self.ammo_nails = 999;
378                                                         self.ammo_cells = 999;
379                                                         self.ammo_shells = 999;
380                                                         self.health = start_health;
381                                                         self.armorvalue = start_armorvalue;
382                                                         self.weapons |= weaponsInMap;
383                                                         self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
384                                                         self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
385                                                         self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
386                                                 }
387                                                 else if(self.deadflag != DEAD_NO)
388                                                         sprint(self, "UR DEAD AHAHAH))\n");
389                                                 else
390                                                         sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
391                                                 break;
392                                         case 143:
393                                                 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))
394                                                 {
395                                                         self.angles_x = -self.angles_x;
396                                                         self.fixangle = TRUE;
397                                                         self.velocity = '0 0 0';
398                                                 }
399                                                 else
400                                                         sprint(self, "Emergency teleport could not find a good location, forget it!\n");
401                                                 break;
402                                         case 144:
403                                                 makevectors(self.v_angle);
404                                                 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
405                                                 if (trace_fraction < 1)
406                                                         printsurfaceinfo(trace_ent, trace_endpos);
407                                                 break;
408                                         case 145:
409                                                 makevectors(self.v_angle);
410                                                 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
411                                                 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
412                                                 break;
413                                 }
414                         }
415                 }
416         }
417         else if(imp >= 103 && imp <= 106)
418         {
419                 if(cvar("g_waypointeditor"))
420                 {
421                         switch(imp)
422                         {
423                                 case 103:
424                                         waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
425                                         break;
426                                 case 104:
427                                         e = navigation_findnearestwaypoint(self, FALSE);
428                                         if (e)
429                                                 waypoint_remove(e);
430                                         break;
431                                 case 105:
432                                         waypoint_schedulerelinkall();
433                                         break;
434                                 case 106:
435                                         waypoint_saveall();
436                                         break;
437                         }
438                 }
439         }
440
441         //TetrisImpulses(imp);
442 }