.vector personal_v_angle; // view angles to restore on impulse 77 .vector personal_velocity; // velocity to restore on impulse 77 void CopyBody(float keepvelocity); // changes by LordHavoc on 03/30/04 // cleaned up dummy code // dummies are now removed eventually after being gibbed (norespawn = TRUE) // dummy impulse now checks sv_cheats to prevent players from overwhelming server with dummies // dummies now use player code where possible void player_anim (void); void DummyThink(void) { self.think = DummyThink; self.nextthink = time; SV_PlayerPhysics(); PlayerPreThink(); //player_anim(); PlayerPostThink(); } // from dpmod void printsurfaceinfo(entity e, vector v) { local float surfnum, numpoints, vnum; local string s; local vector n; surfnum = getsurfacenearpoint(e, v); if (surfnum >= 0) { sprint(self, "texture: "); s = getsurfacetexture(e, surfnum); sprint(self, s); sprint(self, " normal: "); n = getsurfacenormal(e, surfnum); sprint(self, vtos(n)); sprint(self, " "); numpoints = getsurfacenumpoints(e, surfnum); sprint(self, ftos(numpoints)); sprint(self, " verts:"); vnum = 0; while (vnum < numpoints) { sprint(self, " "); n = getsurfacepoint(e, surfnum, vnum); sprint(self, vtos(n)); vnum = vnum + 1; } sprint(self, " point tested: "); sprint(self, vtos(v)); sprint(self, " nearest point on surface: "); n = getsurfaceclippedpoint(e, surfnum, v); sprint(self, vtos(n)); sprint(self, "\n"); } }; /* * Impulse map: * * 0 reserved (no input) * 1 to 9, 14: weapon shortcuts * 10: next weapon according to linear list * 11: most recently used weapon * 12: previous weapon according to linear list * 13: best weapon according to priority list * 15: next weapon according to priority list * 16: previous weapon according to priority list * 17: throw weapon * 18: next weapon according to sbar_hudselector 1 list * 19: previous weapon according to sbar_hudselector 1 list * * 30 to 39: create waypoints * 47: clear personal waypoints * 48: clear team waypoints * 49: turn base waypoints on/off * * 99: loaded * * 140: moving clone * 141: ctf speedrun * 142: fixed clone * 143: emergency teleport * 144: printsurfaceinfo * 145: distance * * TODO: * 200 to 209: prev weapon shortcuts * 210 to 219: best weapon shortcuts * 220 to 229: next weapon shortcuts * 230 to 253: individual weapons (up to 24) */ void ImpulseCommands (void) { local float imp; vector start, end, enddown; float i; float m; float good, evil, evilsurf; float maxattempts; vector org, delta; float wep; entity e; imp = self.impulse; if (!imp || gameover) return; self.impulse = 0; if (timeoutStatus == 2) //don't allow any impulses while the game is paused return; if (imp >= 1 && imp <= 9) { // weapon switching impulses if(self.deadflag == DEAD_NO) W_NextWeaponOnImpulse(imp); else self.impulse = imp; // retry in next frame } else if(imp >= 10 && imp <= 19) { if(self.deadflag == DEAD_NO) { switch(imp) { case 10: W_NextWeapon (0); break; case 11: W_SwitchWeapon (self.cnt); // previously used break; case 12: W_PreviousWeapon (0); break; case 13: W_SwitchWeapon (w_getbestweapon(self)); break; case 14: W_NextWeaponOnImpulse(0); break; case 15: W_NextWeapon (2); break; case 16: W_PreviousWeapon (2); break; case 17: if (!g_minstagib) W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE); break; case 18: W_NextWeapon (1); break; case 19: W_PreviousWeapon (1); break; } } else self.impulse = imp; // retry in next frame } else if(imp >= 200 && imp <= 229) { if(self.deadflag == DEAD_NO) { // custom order weapon cycling i = mod(imp, 10); m = (imp - (210 + i)); // <0 for prev, =0 for best, >0 for next W_CycleWeapon(self.(cvar_cl_weaponpriorities[i]), m); } else self.impulse = imp; // retry in next frame } else if(imp >= 230 && imp <= 253) { if(self.deadflag == DEAD_NO) W_SwitchWeapon (imp - 230 + WEP_FIRST); else self.impulse = imp; // retry in next frame } // deploy waypoints else if (imp >= 30 && imp <= 49) { switch(imp) { case 30: WaypointSprite_DeployPersonal("waypoint", self.origin); self.personal_v_angle = self.v_angle; self.personal_velocity = self.velocity; sprint(self, "personal waypoint spawned at location\n"); break; case 31: WaypointSprite_DeployPersonal("waypoint", self.cursor_trace_endpos); self.personal_v_angle = self.v_angle; self.personal_velocity = '0 0 0'; sprint(self, "personal waypoint spawned at crosshair\n"); break; case 32: if(vlen(self.death_origin)) { WaypointSprite_DeployPersonal("waypoint", self.death_origin); self.personal_v_angle = self.v_angle; self.personal_velocity = '0 0 0'; sprint(self, "personal waypoint spawned at death location\n"); } break; case 33: if(self.deadflag == DEAD_NO && teams_matter) { WaypointSprite_Attach("helpme", TRUE); sprint(self, "HELP ME attached\n"); } break; case 34: WaypointSprite_DeployFixed("here", FALSE, self.origin); sprint(self, "HERE spawned at location\n"); break; case 35: WaypointSprite_DeployFixed("here", FALSE, self.cursor_trace_endpos); sprint(self, "HERE spawned at crosshair\n"); break; case 36: if(vlen(self.death_origin)) { WaypointSprite_DeployFixed("here", FALSE, self.death_origin); sprint(self, "HERE spawned at death location\n"); } break; case 37: WaypointSprite_DeployFixed("danger", FALSE, self.origin); sprint(self, "DANGER spawned at location\n"); break; case 38: WaypointSprite_DeployFixed("danger", FALSE, self.cursor_trace_endpos); sprint(self, "DANGER spawned at crosshair\n"); break; case 39: if(vlen(self.death_origin)) { WaypointSprite_DeployFixed("danger", FALSE, self.death_origin); sprint(self, "DANGER spawned at death location\n"); } break; case 47: WaypointSprite_ClearPersonal(); sprint(self, "personal waypoint cleared\n"); break; case 48: WaypointSprite_ClearOwned(); sprint(self, "all waypoints cleared\n"); break; case 49: self.cvar_cl_hidewaypoints = !(self.cvar_cl_hidewaypoints); sprint(self, "fixed waypoints now "); if(self.cvar_cl_hidewaypoints) sprint(self, "OFF\n"); else sprint(self, "ON\n"); break; } } else if(imp >= 140 && imp <= 149 || imp == 99) // 10 cheats ought to be enough for anyone { if(sv_cheats) if(self.deadflag == DEAD_NO) { switch(imp) { case 99: self.weapons |= WEPBIT_ALL; self.items |= IT_UNLIMITED_AMMO; self.ammo_shells = g_pickup_shells_max; self.ammo_nails = g_pickup_nails_max; self.ammo_rockets = g_pickup_rockets_max; self.ammo_cells = g_pickup_cells_max; self.health = g_pickup_healthsmall_max; self.armorvalue = g_pickup_armorsmall_max; self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn"); self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn"); self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn"); // precache weapon models/sounds wep = WEP_FIRST; while (wep <= WEP_LAST) { weapon_action(wep, WR_PRECACHE); wep = wep + 1; } break; case 140: makevectors (self.v_angle); self.velocity = self.velocity + v_forward * 300; CopyBody(1); self.lip += 1; self.velocity = self.velocity - v_forward * 300; break; case 141: if(self.waypointsprite_deployed_personal) { self.speedrunning = TRUE; tracebox(self.waypointsprite_deployed_personal.origin, self.mins, self.maxs, self.waypointsprite_deployed_personal.origin, MOVE_WORLDONLY, self); if(trace_startsolid) { sprint(self, "Cannot move there, cheater - only waypoints set using g_waypointsprite_personal work\n"); } else { // Abort speedrun, teleport back setorigin(self, self.waypointsprite_deployed_personal.origin); self.oldvelocity = self.velocity = self.personal_velocity; self.angles = self.personal_v_angle; self.fixangle = TRUE; if(self.flagcarried) { bprint("The ", self.flagcarried.netname, " was returned to base by its carrier\n"); ReturnFlag(self.flagcarried); } } self.ammo_rockets = 999; self.ammo_nails = 999; self.ammo_cells = 999; self.ammo_shells = 999; self.health = start_health; self.armorvalue = start_armorvalue; self.weapons |= weaponsInMap; self.pauserotarmor_finished = time + cvar("g_balance_pause_armor_rot_spawn"); self.pauserothealth_finished = time + cvar("g_balance_pause_health_rot_spawn"); self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn"); } else if(self.deadflag != DEAD_NO) sprint(self, "UR DEAD AHAHAH))\n"); else sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n"); break; case 142: CopyBody(0); self.lip += 1; break; case 143: good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP; evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER; evilsurf = Q3SURFACEFLAG_SKY; m = self.dphitcontentsmask; self.dphitcontentsmask = good | evil; org = world.mins; delta = world.maxs - world.mins; maxattempts = ((sv_cheats >= 2) ? 100000 : 100); for(i = 0; i < maxattempts; ++i) { start_x = org_x + random() * delta_x; start_y = org_y + random() * delta_y; start_z = org_z + random() * delta_z; // rule 1: start inside world bounds, and outside // solid, and don't start from somewhere where you can // fall down to evil tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; if(trace_startsolid) continue; dprint("hit contents ", ftos(trace_dphitcontents), "\n"); if(trace_dphitcontents & evil) continue; if(trace_dphitq3surfaceflags & evilsurf) continue; // rule 2: if we are too high, lower the point if(trace_fraction * delta_z > 1024) start = trace_endpos + '0 0 1024'; enddown = trace_endpos; // these can be traceLINES as we already verified the starting box traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self); if(trace_fraction >= 1) continue; end_x = org_x + random() * delta_x; end_y = org_y + random() * delta_y; end_z = org_z + random() * delta_z; end = start + normalize(end - start) * vlen(delta); // rule 3: start TO end must not be too short tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self); if(trace_startsolid) continue; if(trace_fraction < 256 / vlen(delta)) continue; // rule 4: don't want to look at sky if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) continue; // rule 5: we must not end up in trigger_hurt if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown)) { dprint("trigger_hurt! ouch! and nothing else could find it!\n"); continue; } break; } if(i < maxattempts) { self.origin = start; self.angles = vectoangles(end - start); self.angles_x = -self.angles_x; self.fixangle = TRUE; self.velocity = '0 0 0'; dprint("Needed ", ftos(i + 1), " attempts\n"); } else sprint(self, "Emergency teleport could not find a good location, forget it!\n"); self.dphitcontentsmask = m; break; case 144: makevectors(self.v_angle); traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, FALSE, self); if (trace_fraction < 1) printsurfaceinfo(trace_ent, trace_endpos); break; case 145: makevectors(self.v_angle); traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * 65536, FALSE, self); sprint(self, strcat("distance: ", ftos(fabs(vlen(trace_endpos - (self.origin + self.view_ofs)))), "\n")); break; } } } else if(imp >= 103 && imp <= 106) { if(cvar("g_waypointeditor")) { switch(imp) { case 103: waypoint_schedulerelink(waypoint_spawn(self.origin, self.origin, 0)); break; case 104: e = navigation_findnearestwaypoint(self, FALSE); if (e) waypoint_remove(e); break; case 105: waypoint_schedulerelinkall(); break; case 106: waypoint_saveall(); break; } } } //TetrisImpulses(imp); }