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));
139 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
144 self.impulse = imp; // retry in next frame
146 else if(imp >= 200 && imp <= 229)
148 if(self.deadflag == DEAD_NO)
150 // custom order weapon cycling
152 m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next
153 W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m);
156 self.impulse = imp; // retry in next frame
158 else if(imp >= 230 && imp <= 253)
160 if(self.deadflag == DEAD_NO)
161 W_SwitchWeapon (imp - 230 + WEP_FIRST);
163 self.impulse = imp; // retry in next frame
166 else if (imp >= 30 && imp <= 49)
171 WaypointSprite_DeployPersonal("waypoint", self.origin);
172 self.personal_v_angle = self.v_angle;
173 self.personal_velocity = self.velocity;
174 sprint(self, "personal waypoint spawned at location\n");
177 WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
178 self.personal_v_angle = self.v_angle;
179 self.personal_velocity = '0 0 0';
180 sprint(self, "personal waypoint spawned at crosshair\n");
183 if(vlen(self.death_origin))
185 WaypointSprite_DeployPersonal("waypoint", self.death_origin);
186 self.personal_v_angle = self.v_angle;
187 self.personal_velocity = '0 0 0';
188 sprint(self, "personal waypoint spawned at death location\n");
192 if(self.deadflag == DEAD_NO && teams_matter)
194 WaypointSprite_Attach("helpme", TRUE);
195 sprint(self, "HELP ME attached\n");
199 WaypointSprite_DeployFixed("here", FALSE, self.origin);
200 sprint(self, "HERE spawned at location\n");
203 WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
204 sprint(self, "HERE spawned at crosshair\n");
207 if(vlen(self.death_origin))
209 WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
210 sprint(self, "HERE spawned at death location\n");
214 WaypointSprite_DeployFixed("danger", FALSE, self.origin);
215 sprint(self, "DANGER spawned at location\n");
218 WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
219 sprint(self, "DANGER spawned at crosshair\n");
222 if(vlen(self.death_origin))
224 WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
225 sprint(self, "DANGER spawned at death location\n");
229 WaypointSprite_ClearPersonal();
230 sprint(self, "personal waypoint cleared\n");
233 WaypointSprite_ClearOwned();
234 sprint(self, "all waypoints cleared\n");
237 self.cvar_cl_hidewaypoints = !(self.cvar_cl_hidewaypoints);
238 sprint(self, "fixed waypoints now ");
239 if(self.cvar_cl_hidewaypoints)
240 sprint(self, "OFF\n");
242 sprint(self, "ON\n");
246 else if(imp >= 140 && imp <= 149 || imp == 99) // 10 cheats ought to be enough for anyone
249 if(self.deadflag == DEAD_NO)
254 self.weapons |= WEPBIT_ALL;
255 self.ammo_shells = g_pickup_shells_max;
256 self.ammo_nails = g_pickup_nails_max;
257 self.ammo_rockets = g_pickup_rockets_max;
258 self.ammo_cells = g_pickup_cells_max;
259 self.health = g_pickup_healthsmall_max;
260 self.armorvalue = g_pickup_armorsmall_max;
261 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
262 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
263 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
264 // precache weapon models/sounds
266 while (wep <= WEP_LAST)
268 weapon_action(wep, WR_PRECACHE);
273 makevectors (self.v_angle);
274 self.velocity = self.velocity + v_forward * 300;
277 self.velocity = self.velocity - v_forward * 300;
280 if(self.waypointsprite_deployed_personal)
282 self.speedrunning = TRUE;
283 tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
286 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
290 // Abort speedrun, teleport back
291 setorigin(self, self.waypointsprite_deployed_personal.origin);
292 self.oldvelocity = self.velocity = self.personal_velocity;
293 self.angles = self.personal_v_angle;
294 self.fixangle = TRUE;
297 bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
298 ReturnFlag(self.flagcarried);
301 self.ammo_rockets = 999;
302 self.ammo_nails = 999;
303 self.ammo_cells = 999;
304 self.ammo_shells = 999;
305 self.health = start_health;
306 self.armorvalue = start_armorvalue;
307 self.weapons |= weaponsInMap;
308 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
309 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
310 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
312 else if(self.deadflag != DEAD_NO)
313 sprint(self, "UR DEAD AHAHAH))\n");
315 sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
322 good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP;
323 evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER;
324 evilsurf = Q3SURFACEFLAG_SKY;
326 m = self.dphitcontentsmask;
327 self.dphitcontentsmask = good | evil;
330 delta = world.maxs - world.mins;
332 maxattempts = ((sv_cheats >= 2) ? 100000 : 100);
334 for(i = 0; i < maxattempts; ++i)
336 start_x = org_x + random() * delta_x;
337 start_y = org_y + random() * delta_y;
338 start_z = org_z + random() * delta_z;
340 // rule 1: start inside world bounds, and outside
341 // solid, and don't start from somewhere where you can
343 tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self);
344 if(trace_fraction >= 1)
348 dprint("hit contents ", ftos(trace_dphitcontents), "\n");
349 if(trace_dphitcontents & evil)
351 if(trace_dphitq3surfaceflags & evilsurf)
354 // rule 2: if we are too high, lower the point
355 if(trace_fraction * delta_z > 1024)
356 start = trace_endpos + '0 0 1024';
357 enddown = trace_endpos;
359 // these can be traceLINES as we already verified the starting box
360 traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self);
361 if(trace_fraction >= 1)
363 traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self);
364 if(trace_fraction >= 1)
366 traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self);
367 if(trace_fraction >= 1)
369 traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self);
370 if(trace_fraction >= 1)
372 traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self);
373 if(trace_fraction >= 1)
376 end_x = org_x + random() * delta_x;
377 end_y = org_y + random() * delta_y;
378 end_z = org_z + random() * delta_z;
379 end = start + normalize(end - start) * vlen(delta);
381 // rule 3: start TO end must not be too short
382 tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
385 if(trace_fraction < 256 / vlen(delta))
388 // rule 4: don't want to look at sky
389 if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
392 // rule 5: we must not end up in trigger_hurt
393 if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown))
395 dprint("trigger_hurt! ouch! and nothing else could find it!\n");
405 self.angles = vectoangles(end - start);
406 self.angles_x = -self.angles_x;
407 self.fixangle = TRUE;
408 self.velocity = '0 0 0';
409 dprint("Needed ", ftos(i + 1), " attempts\n");
412 sprint(self, "Emergency teleport could not find a good location, forget it!\n");
414 self.dphitcontentsmask = m;
417 makevectors(self.v_angle);
418 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
419 if (trace_fraction < 1)
420 printsurfaceinfo(trace_ent, trace_endpos);
423 makevectors(self.v_angle);
424 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
425 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
430 else if(imp >= 103 && imp <= 106)
432 if(cvar("g_waypointeditor"))
437 waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
440 e = navigation_findnearestwaypoint(self, FALSE);
445 waypoint_schedulerelinkall();
454 //TetrisImpulses(imp);