1 .vector personal_v_angle; // view angles to restore on impulse 77
2 .vector personal_velocity; // velocity to restore on impulse 77
4 void CopyBody(float keepvelocity);
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
12 void player_anim (void);
15 self.think = DummyThink;
16 self.nextthink = time;
24 void printsurfaceinfo(entity e, vector v)
26 local float surfnum, numpoints, vnum;
29 surfnum = getsurfacenearpoint(e, v);
32 sprint(self, "texture: ");
33 s = getsurfacetexture(e, surfnum);
35 sprint(self, " normal: ");
36 n = getsurfacenormal(e, surfnum);
37 sprint(self, vtos(n));
39 numpoints = getsurfacenumpoints(e, surfnum);
40 sprint(self, ftos(numpoints));
41 sprint(self, " verts:");
43 while (vnum < numpoints)
46 n = getsurfacepoint(e, surfnum, vnum);
47 sprint(self, vtos(n));
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));
62 * 0 reserved (no input)
63 * 1 to 9: weapon shortcuts
65 * 11: most recently used weapon
70 * 30 to 39: create waypoints
71 * 47: clear personal waypoints
72 * 48: clear team waypoints
73 * 49: turn base waypoints on/off
80 * 143: emergency teleport
81 * 144: printsurfaceinfo
85 * 200 to 209: prev weapon shortcuts
86 * 210 to 219: best weapon shortcuts
87 * 220 to 229: next weapon shortcuts
88 * 230 to 253: individual weapons (up to 24)
91 void ImpulseCommands (void)
94 vector start, end, enddown;
97 float good, evil, evilsurf;
104 if (!imp || gameover)
108 if (timeoutStatus == 2) //don't allow any impulses while the game is paused
111 if (imp >= 1 && imp <= 9)
113 // weapon switching impulses
114 if(self.deadflag == DEAD_NO)
115 W_NextWeaponOnImpulse(imp);
117 self.impulse = imp; // retry in next frame
119 else if(imp >= 10 && imp <= 17)
121 if(self.deadflag == DEAD_NO)
129 W_SwitchWeapon (self.cnt); // previously used
135 W_SwitchWeapon (w_getbestweapon(self));
138 W_NextWeaponOnImpulse(0);
142 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
147 self.impulse = imp; // retry in next frame
149 else if(imp >= 200 && imp <= 229)
151 if(self.deadflag == DEAD_NO)
153 // custom order weapon cycling
155 m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next
156 W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m);
159 self.impulse = imp; // retry in next frame
161 else if(imp >= 230 && imp <= 253)
163 if(self.deadflag == DEAD_NO)
164 W_SwitchWeapon (imp - 230 + WEP_FIRST);
166 self.impulse = imp; // retry in next frame
169 else if (imp >= 30 && imp <= 49)
174 WaypointSprite_DeployPersonal("waypoint", self.origin);
175 self.personal_v_angle = self.v_angle;
176 self.personal_velocity = self.velocity;
177 sprint(self, "personal waypoint spawned at location\n");
180 WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
181 self.personal_v_angle = self.v_angle;
182 self.personal_velocity = '0 0 0';
183 sprint(self, "personal waypoint spawned at crosshair\n");
186 if(vlen(self.death_origin))
188 WaypointSprite_DeployPersonal("waypoint", self.death_origin);
189 self.personal_v_angle = self.v_angle;
190 self.personal_velocity = '0 0 0';
191 sprint(self, "personal waypoint spawned at death location\n");
195 if(self.deadflag == DEAD_NO && teams_matter)
197 WaypointSprite_Attach("helpme", TRUE);
198 sprint(self, "HELP ME attached\n");
202 WaypointSprite_DeployFixed("here", FALSE, self.origin);
203 sprint(self, "HERE spawned at location\n");
206 WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
207 sprint(self, "HERE spawned at crosshair\n");
210 if(vlen(self.death_origin))
212 WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
213 sprint(self, "HERE spawned at death location\n");
217 WaypointSprite_DeployFixed("danger", FALSE, self.origin);
218 sprint(self, "DANGER spawned at location\n");
221 WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
222 sprint(self, "DANGER spawned at crosshair\n");
225 if(vlen(self.death_origin))
227 WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
228 sprint(self, "DANGER spawned at death location\n");
232 WaypointSprite_ClearPersonal();
233 sprint(self, "personal waypoint cleared\n");
236 WaypointSprite_ClearOwned();
237 sprint(self, "all waypoints cleared\n");
240 self.cvar_cl_hidewaypoints = !(self.cvar_cl_hidewaypoints);
241 sprint(self, "fixed waypoints now ");
242 if(self.cvar_cl_hidewaypoints)
243 sprint(self, "OFF\n");
245 sprint(self, "ON\n");
249 else if(imp >= 140 && imp <= 149 || imp == 99) // 10 cheats ought to be enough for anyone
252 if(self.deadflag == DEAD_NO)
257 self.weapons |= WEPBIT_ALL;
258 self.items |= IT_UNLIMITED_AMMO;
259 self.ammo_shells = g_pickup_shells_max;
260 self.ammo_nails = g_pickup_nails_max;
261 self.ammo_rockets = g_pickup_rockets_max;
262 self.ammo_cells = g_pickup_cells_max;
263 self.health = g_pickup_healthsmall_max;
264 self.armorvalue = g_pickup_armorsmall_max;
265 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
266 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
267 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
268 // precache weapon models/sounds
270 while (wep <= WEP_LAST)
272 weapon_action(wep, WR_PRECACHE);
277 makevectors (self.v_angle);
278 self.velocity = self.velocity + v_forward * 300;
281 self.velocity = self.velocity - v_forward * 300;
284 if(self.waypointsprite_deployed_personal)
286 self.speedrunning = TRUE;
287 tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
290 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
294 // Abort speedrun, teleport back
295 setorigin(self, self.waypointsprite_deployed_personal.origin);
296 self.oldvelocity = self.velocity = self.personal_velocity;
297 self.angles = self.personal_v_angle;
298 self.fixangle = TRUE;
301 bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
302 ReturnFlag(self.flagcarried);
305 self.ammo_rockets = 999;
306 self.ammo_nails = 999;
307 self.ammo_cells = 999;
308 self.ammo_shells = 999;
309 self.health = start_health;
310 self.armorvalue = start_armorvalue;
311 self.weapons |= weaponsInMap;
312 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
313 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
314 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
316 else if(self.deadflag != DEAD_NO)
317 sprint(self, "UR DEAD AHAHAH))\n");
319 sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
326 good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP;
327 evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER;
328 evilsurf = Q3SURFACEFLAG_SKY;
330 m = self.dphitcontentsmask;
331 self.dphitcontentsmask = good | evil;
334 delta = world.maxs - world.mins;
336 maxattempts = ((sv_cheats >= 2) ? 100000 : 100);
338 for(i = 0; i < maxattempts; ++i)
340 start_x = org_x + random() * delta_x;
341 start_y = org_y + random() * delta_y;
342 start_z = org_z + random() * delta_z;
344 // rule 1: start inside world bounds, and outside
345 // solid, and don't start from somewhere where you can
347 tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self);
348 if(trace_fraction >= 1)
352 dprint("hit contents ", ftos(trace_dphitcontents), "\n");
353 if(trace_dphitcontents & evil)
355 if(trace_dphitq3surfaceflags & evilsurf)
358 // rule 2: if we are too high, lower the point
359 if(trace_fraction * delta_z > 1024)
360 start = trace_endpos + '0 0 1024';
361 enddown = trace_endpos;
363 // these can be traceLINES as we already verified the starting box
364 traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self);
365 if(trace_fraction >= 1)
367 traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self);
368 if(trace_fraction >= 1)
370 traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self);
371 if(trace_fraction >= 1)
373 traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self);
374 if(trace_fraction >= 1)
376 traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self);
377 if(trace_fraction >= 1)
380 end_x = org_x + random() * delta_x;
381 end_y = org_y + random() * delta_y;
382 end_z = org_z + random() * delta_z;
383 end = start + normalize(end - start) * vlen(delta);
385 // rule 3: start TO end must not be too short
386 tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
389 if(trace_fraction < 256 / vlen(delta))
392 // rule 4: don't want to look at sky
393 if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
396 // rule 5: we must not end up in trigger_hurt
397 if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown))
399 dprint("trigger_hurt! ouch! and nothing else could find it!\n");
409 self.angles = vectoangles(end - start);
410 self.angles_x = -self.angles_x;
411 self.fixangle = TRUE;
412 self.velocity = '0 0 0';
413 dprint("Needed ", ftos(i + 1), " attempts\n");
416 sprint(self, "Emergency teleport could not find a good location, forget it!\n");
418 self.dphitcontentsmask = m;
421 makevectors(self.v_angle);
422 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
423 if (trace_fraction < 1)
424 printsurfaceinfo(trace_ent, trace_endpos);
427 makevectors(self.v_angle);
428 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
429 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
434 else if(imp >= 103 && imp <= 106)
436 if(cvar("g_waypointeditor"))
441 waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
444 e = navigation_findnearestwaypoint(self, FALSE);
449 waypoint_schedulerelinkall();
458 //TetrisImpulses(imp);