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