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));
59 void ImpulseCommands (void)
67 if (timeoutStatus == 2) //don't allow any impulses while the game is paused
70 if (imp >= 1 && imp <= 12)
72 // weapon switching impulses
73 if(self.deadflag == DEAD_NO)
81 else if (imp == 11) // last weapon
82 W_SwitchWeapon (self.cnt);
85 self.impulse = imp; // retry in next frame
90 if(self.deadflag == DEAD_NO)
92 W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
95 else if (imp >= 30 && imp <= 49)
99 WaypointSprite_DeployPersonal("waypoint", self.origin);
100 self.personal_v_angle = self.v_angle;
101 self.personal_velocity = self.velocity;
102 sprint(self, "personal waypoint spawned at location\n");
106 WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos);
107 self.personal_v_angle = self.v_angle;
108 self.personal_velocity = '0 0 0';
109 sprint(self, "personal waypoint spawned at crosshair\n");
111 else if(imp == 32 && vlen(self.death_origin))
113 WaypointSprite_DeployPersonal("waypoint", self.death_origin);
114 self.personal_v_angle = self.v_angle;
115 self.personal_velocity = '0 0 0';
116 sprint(self, "personal waypoint spawned at death location\n");
118 else if(imp == 33 && self.deadflag == DEAD_NO && teams_matter)
120 WaypointSprite_Attach("helpme", TRUE);
121 sprint(self, "HELP ME attached\n");
125 WaypointSprite_DeployFixed("here", FALSE, self.origin);
126 sprint(self, "HERE spawned at location\n");
130 WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos);
131 sprint(self, "HERE spawned at crosshair\n");
133 else if(imp == 36 && vlen(self.death_origin))
135 WaypointSprite_DeployFixed("here", FALSE, self.death_origin);
136 sprint(self, "HERE spawned at death location\n");
140 WaypointSprite_DeployFixed("danger", FALSE, self.origin);
141 sprint(self, "DANGER spawned at location\n");
145 WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos);
146 sprint(self, "DANGER spawned at crosshair\n");
148 else if(imp == 39 && vlen(self.death_origin))
150 WaypointSprite_DeployFixed("danger", FALSE, self.death_origin);
151 sprint(self, "DANGER spawned at death location\n");
155 WaypointSprite_ClearPersonal();
156 sprint(self, "personal waypoint cleared\n");
160 WaypointSprite_ClearOwned();
161 sprint(self, "all waypoints cleared\n");
165 self.cvar_cl_hidewaypoints = !(self.cvar_cl_hidewaypoints);
166 sprint(self, "fixed waypoints now ");
167 if(self.cvar_cl_hidewaypoints)
168 sprint(self, "OFF\n");
170 sprint(self, "ON\n");
179 makevectors(self.v_angle);
180 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self);
181 if (trace_fraction < 1)
182 printsurfaceinfo(trace_ent, trace_endpos);
186 makevectors(self.v_angle);
187 traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self);
188 sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n"));
190 else if(self.deadflag == DEAD_NO)
194 if(self.waypointsprite_deployed_personal)
196 self.speedrunning = TRUE;
197 tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self);
200 sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n");
204 // Abort speedrun, teleport back
205 setorigin(self, self.waypointsprite_deployed_personal.origin);
206 self.oldvelocity = self.velocity = self.personal_velocity;
207 self.angles = self.personal_v_angle;
208 self.fixangle = TRUE;
211 bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n");
212 ReturnFlag(self.flagcarried);
215 self.ammo_rockets = 999;
216 self.ammo_nails = 999;
217 self.ammo_cells = 999;
218 self.ammo_shells = 999;
219 self.health = start_health;
220 self.armorvalue = start_armorvalue;
221 self.items |= itemsInMap & (IT_LASER | IT_SHOTGUN | IT_UZI | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER);
222 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
223 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
224 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
227 sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
231 self.items |= (IT_LASER | IT_UZI | IT_SHOTGUN | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER);
232 self.ammo_shells = g_pickup_shells_max;
233 self.ammo_nails = g_pickup_nails_max;
234 self.ammo_rockets = g_pickup_rockets_max;
235 self.ammo_cells = g_pickup_cells_max;
236 self.health = g_pickup_healthsmall_max;
237 self.armorvalue = g_pickup_armorsmall_max;
238 self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn");
239 self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn");
240 self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
241 // precache weapon models/sounds
244 while (wep <= WEP_LAST)
246 weapon_action(wep, WR_PRECACHE);
252 makevectors (self.v_angle);
253 self.velocity = self.velocity + v_forward * 300;
256 self.velocity = self.velocity - v_forward * 300;
263 else if (imp == 143) // actually: impulse 911
265 vector start, end, enddown;
268 float good, evil, evilsurf;
272 good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP;
273 evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER;
274 evilsurf = Q3SURFACEFLAG_SKY;
276 m = self.dphitcontentsmask;
277 self.dphitcontentsmask = good | evil;
280 delta = world.maxs - world.mins;
282 maxattempts = ((sv_cheats >= 2) ? 100000 : 100);
284 for(i = 0; i < maxattempts; ++i)
286 start_x = org_x + random() * delta_x;
287 start_y = org_y + random() * delta_y;
288 start_z = org_z + random() * delta_z;
290 // rule 1: start inside world bounds, and outside
291 // solid, and don't start from somewhere where you can
293 tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self);
294 if(trace_fraction >= 1)
298 dprint("hit contents ", ftos(trace_dphitcontents), "\n");
299 if(trace_dphitcontents & evil)
301 if(trace_dphitq3surfaceflags & evilsurf)
304 // rule 2: if we are too high, lower the point
305 if(trace_fraction * delta_z > 1024)
306 start = trace_endpos + '0 0 1024';
307 enddown = trace_endpos;
309 // these can be traceLINES as we already verified the starting box
310 traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self);
311 if(trace_fraction >= 1)
313 traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self);
314 if(trace_fraction >= 1)
316 traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self);
317 if(trace_fraction >= 1)
319 traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self);
320 if(trace_fraction >= 1)
322 traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self);
323 if(trace_fraction >= 1)
326 end_x = org_x + random() * delta_x;
327 end_y = org_y + random() * delta_y;
328 end_z = org_z + random() * delta_z;
329 end = start + normalize(end - start) * vlen(delta);
331 // rule 3: start TO end must not be too short
332 tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
335 if(trace_fraction < 256 / vlen(delta))
338 // rule 4: don't want to look at sky
339 if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
342 // rule 5: we must not end up in trigger_hurt
343 if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown))
345 dprint("trigger_hurt! ouch! and nothing else could find it!\n");
355 self.angles = vectoangles(end - start);
356 self.angles_x = -self.angles_x;
357 self.fixangle = TRUE;
358 self.velocity = '0 0 0';
359 dprint("Needed ", ftos(i + 1), " attempts\n");
362 sprint(self, "Emergency teleport could not find a good location, forget it!\n");
364 self.dphitcontentsmask = m;
370 if (cvar("g_waypointeditor"))
373 if (imp == 103) waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0));
374 else if (imp == 104) {e = navigation_findnearestwaypoint(self, FALSE);if (e) waypoint_remove(e);}
375 else if (imp == 105) waypoint_schedulerelinkall();
376 else if (imp == 106) waypoint_saveall();
379 //TetrisImpulses(imp);