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 * 19: printsurfaceinfo
72 * 30 to 39: create waypoints
73 * 47: clear personal waypoints
74 * 48: clear team waypoints
75 * 49: turn base waypoints on/off
78 * 143: emergency teleport
81 * 200 to 219: individual weapons
82 * 220 to 229: next weapon shortcuts
83 * 230 to 239: prev weapon shortcuts
84 * 240 to 249: best weapon shortcuts
87 void ImpulseCommands (void)
95 if (timeoutStatus == 2) //don't allow any impulses while the game is paused
98 if (imp >= 1 && imp <= 12)
100 // weapon switching impulses
101 if(self.deadflag == DEAD_NO)
104 W_SwitchWeapon (imp);
109 else if (imp == 11) // last weapon
110 W_SwitchWeapon (self.cnt);
113 self.impulse = imp; // retry in next frame
118 if(self.deadflag == DEAD_NO)
120 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
123 else if (imp >= 30 && imp <= 49)
127 WaypointSprite_DeployPersonal("waypoint", self.origin);
128 self.personal_v_angle = self.v_angle;
129 self.personal_velocity = self.velocity;
130 sprint(self, "personal waypoint spawned at location\n");
134 WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
135 self.personal_v_angle = self.v_angle;
136 self.personal_velocity = '0 0 0';
137 sprint(self, "personal waypoint spawned at crosshair\n");
139 else if(imp == 32 && vlen(self.death_origin))
141 WaypointSprite_DeployPersonal("waypoint", self.death_origin);
142 self.personal_v_angle = self.v_angle;
143 self.personal_velocity = '0 0 0';
144 sprint(self, "personal waypoint spawned at death location\n");
146 else if(imp == 33 && self.deadflag == DEAD_NO && teams_matter)
148 WaypointSprite_Attach("helpme", TRUE);
149 sprint(self, "HELP ME attached\n");
153 WaypointSprite_DeployFixed("here", FALSE, self.origin);
154 sprint(self, "HERE spawned at location\n");
158 WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
159 sprint(self, "HERE spawned at crosshair\n");
161 else if(imp == 36 && vlen(self.death_origin))
163 WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
164 sprint(self, "HERE spawned at death location\n");
168 WaypointSprite_DeployFixed("danger", FALSE, self.origin);
169 sprint(self, "DANGER spawned at location\n");
173 WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
174 sprint(self, "DANGER spawned at crosshair\n");
176 else if(imp == 39 && vlen(self.death_origin))
178 WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
179 sprint(self, "DANGER spawned at death location\n");
183 WaypointSprite_ClearPersonal();
184 sprint(self, "personal waypoint cleared\n");
188 WaypointSprite_ClearOwned();
189 sprint(self, "all waypoints cleared\n");
193 self.cvar_cl_hidewaypoints = !(self.cvar_cl_hidewaypoints);
194 sprint(self, "fixed waypoints now ");
195 if(self.cvar_cl_hidewaypoints)
196 sprint(self, "OFF\n");
198 sprint(self, "ON\n");
207 makevectors(self.v_angle);
208 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
209 if (trace_fraction < 1)
210 printsurfaceinfo(trace_ent, trace_endpos);
214 makevectors(self.v_angle);
215 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
216 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
218 else if(self.deadflag == DEAD_NO)
222 if(self.waypointsprite_deployed_personal)
224 self.speedrunning = TRUE;
225 tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
228 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
232 // Abort speedrun, teleport back
233 setorigin(self, self.waypointsprite_deployed_personal.origin);
234 self.oldvelocity = self.velocity = self.personal_velocity;
235 self.angles = self.personal_v_angle;
236 self.fixangle = TRUE;
239 bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
240 ReturnFlag(self.flagcarried);
243 self.ammo_rockets = 999;
244 self.ammo_nails = 999;
245 self.ammo_cells = 999;
246 self.ammo_shells = 999;
247 self.health = start_health;
248 self.armorvalue = start_armorvalue;
249 self.items |= itemsInMap & (IT_LASER | IT_SHOTGUN | IT_UZI | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER);
250 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
251 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
252 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
255 sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
259 self.items |= (IT_LASER | IT_UZI | IT_SHOTGUN | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER);
260 self.ammo_shells = g_pickup_shells_max;
261 self.ammo_nails = g_pickup_nails_max;
262 self.ammo_rockets = g_pickup_rockets_max;
263 self.ammo_cells = g_pickup_cells_max;
264 self.health = g_pickup_healthsmall_max;
265 self.armorvalue = g_pickup_armorsmall_max;
266 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
267 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
268 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
269 // precache weapon models/sounds
272 while (wep <= WEP_LAST)
274 weapon_action(wep, WR_PRECACHE);
280 makevectors (self.v_angle);
281 self.velocity = self.velocity + v_forward * 300;
284 self.velocity = self.velocity - v_forward * 300;
291 else if (imp == 143) // actually: impulse 911
293 vector start, end, enddown;
296 float good, evil, evilsurf;
300 good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP;
301 evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER;
302 evilsurf = Q3SURFACEFLAG_SKY;
304 m = self.dphitcontentsmask;
305 self.dphitcontentsmask = good | evil;
308 delta = world.maxs - world.mins;
310 maxattempts = ((sv_cheats >= 2) ? 100000 : 100);
312 for(i = 0; i < maxattempts; ++i)
314 start_x = org_x + random() * delta_x;
315 start_y = org_y + random() * delta_y;
316 start_z = org_z + random() * delta_z;
318 // rule 1: start inside world bounds, and outside
319 // solid, and don't start from somewhere where you can
321 tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self);
322 if(trace_fraction >= 1)
326 dprint("hit contents ", ftos(trace_dphitcontents), "\n");
327 if(trace_dphitcontents & evil)
329 if(trace_dphitq3surfaceflags & evilsurf)
332 // rule 2: if we are too high, lower the point
333 if(trace_fraction * delta_z > 1024)
334 start = trace_endpos + '0 0 1024';
335 enddown = trace_endpos;
337 // these can be traceLINES as we already verified the starting box
338 traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self);
339 if(trace_fraction >= 1)
341 traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self);
342 if(trace_fraction >= 1)
344 traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self);
345 if(trace_fraction >= 1)
347 traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self);
348 if(trace_fraction >= 1)
350 traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self);
351 if(trace_fraction >= 1)
354 end_x = org_x + random() * delta_x;
355 end_y = org_y + random() * delta_y;
356 end_z = org_z + random() * delta_z;
357 end = start + normalize(end - start) * vlen(delta);
359 // rule 3: start TO end must not be too short
360 tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
363 if(trace_fraction < 256 / vlen(delta))
366 // rule 4: don't want to look at sky
367 if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
370 // rule 5: we must not end up in trigger_hurt
371 if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown))
373 dprint("trigger_hurt! ouch! and nothing else could find it!\n");
383 self.angles = vectoangles(end - start);
384 self.angles_x = -self.angles_x;
385 self.fixangle = TRUE;
386 self.velocity = '0 0 0';
387 dprint("Needed ", ftos(i + 1), " attempts\n");
390 sprint(self, "Emergency teleport could not find a good location, forget it!\n");
392 self.dphitcontentsmask = m;
398 if (cvar("g_waypointeditor"))
401 if (imp == 103) waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
402 else if (imp == 104) {e = navigation_findnearestwaypoint(self, FALSE);if (e) waypoint_remove(e);}
403 else if (imp == 105) waypoint_schedulerelinkall();
404 else if (imp == 106) waypoint_saveall();
407 //TetrisImpulses(imp);