Advertisement
Guest User

CS:S_MOVEMENTCODE

a guest
Dec 1st, 2015
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.61 KB | None | 0 0
  1.  
  2. */
  3. // sv_user.c -- server code for moving users
  4.  
  5. #include "quakedef.h"
  6.  
  7. edict_t *sv_player;
  8.  
  9. extern  cvar_t  sv_friction;
  10. cvar_t  sv_edgefriction = {"edgefriction", "2"};
  11. extern  cvar_t  sv_stopspeed;
  12.  
  13. static  vec3_t      forward, right, up;
  14.  
  15. vec3_t  wishdir;
  16. float   wishspeed;
  17.  
  18. // world
  19. float   *angles;
  20. float   *origin;
  21. float   *velocity;
  22.  
  23. qboolean    onground;
  24.  
  25. usercmd_t   cmd;
  26.  
  27. cvar_t  sv_idealpitchscale = {"sv_idealpitchscale","0.8"};
  28.  
  29.  
  30. /*
  31. ===============
  32. SV_SetIdealPitch
  33. ===============
  34. */
  35. #define MAX_FORWARD 6
  36. void SV_SetIdealPitch (void)
  37. {
  38.     float   angleval, sinval, cosval;
  39.     trace_t tr;
  40.     vec3_t  top, bottom;
  41.     float   z[MAX_FORWARD];
  42.     int     i, j;
  43.     int     step, dir, steps;
  44.  
  45.     if (!((int)sv_player->v.flags & FL_ONGROUND))
  46.         return;
  47.        
  48.     angleval = sv_player->v.angles[YAW] * M_PI*2 / 360;
  49.     sinval = sin(angleval);
  50.     cosval = cos(angleval);
  51.  
  52.     for (i=0 ; i<MAX_FORWARD ; i++)
  53.     {
  54.         top[0] = sv_player->v.origin[0] + cosval*(i+3)*12;
  55.         top[1] = sv_player->v.origin[1] + sinval*(i+3)*12;
  56.         top[2] = sv_player->v.origin[2] + sv_player->v.view_ofs[2];
  57.        
  58.         bottom[0] = top[0];
  59.         bottom[1] = top[1];
  60.         bottom[2] = top[2] - 160;
  61.        
  62.         tr = SV_Move (top, vec3_origin, vec3_origin, bottom, 1, sv_player);
  63.         if (tr.allsolid)
  64.             return; // looking at a wall, leave ideal the way is was
  65.  
  66.         if (tr.fraction == 1)
  67.             return; // near a dropoff
  68.        
  69.         z[i] = top[2] + tr.fraction*(bottom[2]-top[2]);
  70.     }
  71.    
  72.     dir = 0;
  73.     steps = 0;
  74.     for (j=1 ; j<i ; j++)
  75.     {
  76.         step = z[j] - z[j-1];
  77.         if (step > -ON_EPSILON && step < ON_EPSILON)
  78.             continue;
  79.  
  80.         if (dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ) )
  81.             return;     // mixed changes
  82.  
  83.         steps++;   
  84.         dir = step;
  85.     }
  86.    
  87.     if (!dir)
  88.     {
  89.         sv_player->v.idealpitch = 0;
  90.         return;
  91.     }
  92.    
  93.     if (steps < 2)
  94.         return;
  95.     sv_player->v.idealpitch = -dir * sv_idealpitchscale.value;
  96. }
  97.  
  98.  
  99. /*
  100. ==================
  101. SV_UserFriction
  102.  
  103. ==================
  104. */
  105. void SV_UserFriction (void)
  106. {
  107.     float   *vel;
  108.     float   speed, newspeed, control;
  109.     vec3_t  start, stop;
  110.     float   friction;
  111.     trace_t trace;
  112.    
  113.     vel = velocity;
  114.    
  115.     speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
  116.     if (!speed)
  117.         return;
  118.  
  119. // if the leading edge is over a dropoff, increase friction
  120.     start[0] = stop[0] = origin[0] + vel[0]/speed*16;
  121.     start[1] = stop[1] = origin[1] + vel[1]/speed*16;
  122.     start[2] = origin[2] + sv_player->v.mins[2];
  123.     stop[2] = start[2] - 34;
  124.  
  125.     trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player);
  126.  
  127.     if (trace.fraction == 1.0)
  128.         friction = sv_friction.value*sv_edgefriction.value;
  129.     else
  130.         friction = sv_friction.value;
  131.  
  132. // apply friction  
  133.     control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
  134.     newspeed = speed - host_frametime*control*friction;
  135.    
  136.     if (newspeed < 0)
  137.         newspeed = 0;
  138.     newspeed /= speed;
  139.  
  140.     vel[0] = vel[0] * newspeed;
  141.     vel[1] = vel[1] * newspeed;
  142.     vel[2] = vel[2] * newspeed;
  143. }
  144.  
  145. /*
  146. ==============
  147. SV_Accelerate
  148. ==============
  149. */
  150. cvar_t  sv_maxspeed = {"sv_maxspeed", "320", false, true};
  151. cvar_t  sv_accelerate = {"sv_accelerate", "10"};
  152. #if 0
  153. void SV_Accelerate (vec3_t wishvel)
  154. {
  155.     int         i;
  156.     float       addspeed, accelspeed;
  157.     vec3_t      pushvec;
  158.  
  159.     if (wishspeed == 0)
  160.         return;
  161.  
  162.     VectorSubtract (wishvel, velocity, pushvec);
  163.     addspeed = VectorNormalize (pushvec);
  164.  
  165.     accelspeed = sv_accelerate.value*host_frametime*addspeed;
  166.     if (accelspeed > addspeed)
  167.         accelspeed = addspeed;
  168.    
  169.     for (i=0 ; i<3 ; i++)
  170.         velocity[i] += accelspeed*pushvec[i];  
  171. }
  172. #endif
  173. void SV_Accelerate (void)
  174. {
  175.     int         i;
  176.     float       addspeed, accelspeed, currentspeed;
  177.  
  178.     currentspeed = DotProduct (velocity, wishdir);
  179.     addspeed = wishspeed - currentspeed;
  180.     if (addspeed <= 0)
  181.         return;
  182.     accelspeed = sv_accelerate.value*host_frametime*wishspeed;
  183.     if (accelspeed > addspeed)
  184.         accelspeed = addspeed;
  185.    
  186.     for (i=0 ; i<3 ; i++)
  187.         velocity[i] += accelspeed*wishdir[i];  
  188. }
  189.  
  190. void SV_AirAccelerate (vec3_t wishveloc)
  191. {
  192.     int         i;
  193.     float       addspeed, wishspd, accelspeed, currentspeed;
  194.        
  195.     wishspd = VectorNormalize (wishveloc);
  196.     if (wishspd > 30)
  197.         wishspd = 30;
  198.     currentspeed = DotProduct (velocity, wishveloc);
  199.     addspeed = wishspd - currentspeed;
  200.     if (addspeed <= 0)
  201.         return;
  202. //  accelspeed = sv_accelerate.value * host_frametime;
  203.     accelspeed = sv_accelerate.value*wishspeed * host_frametime;
  204.     if (accelspeed > addspeed)
  205.         accelspeed = addspeed;
  206.    
  207.     for (i=0 ; i<3 ; i++)
  208.         velocity[i] += accelspeed*wishveloc[i];
  209. }
  210.  
  211.  
  212. void DropPunchAngle (void)
  213. {
  214.     float   len;
  215.    
  216.     len = VectorNormalize (sv_player->v.punchangle);
  217.    
  218.     len -= 10*host_frametime;
  219.     if (len < 0)
  220.         len = 0;
  221.     VectorScale (sv_player->v.punchangle, len, sv_player->v.punchangle);
  222. }
  223.  
  224. /*
  225. ===================
  226. SV_WaterMove
  227.  
  228. ===================
  229. */
  230. void SV_WaterMove (void)
  231. {
  232.     int     i;
  233.     vec3_t  wishvel;
  234.     float   speed, newspeed, wishspeed, addspeed, accelspeed;
  235.  
  236. //
  237. // user intentions
  238. //
  239.     AngleVectors (sv_player->v.v_angle, forward, right, up);
  240.  
  241.     for (i=0 ; i<3 ; i++)
  242.         wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
  243.  
  244.     if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove)
  245.         wishvel[2] -= 60;       // drift towards bottom
  246.     else
  247.         wishvel[2] += cmd.upmove;
  248.  
  249.     wishspeed = Length(wishvel);
  250.     if (wishspeed > sv_maxspeed.value)
  251.     {
  252.         VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
  253.         wishspeed = sv_maxspeed.value;
  254.     }
  255.     wishspeed *= 0.7;
  256.  
  257. //
  258. // water friction
  259. //
  260.     speed = Length (velocity);
  261.     if (speed)
  262.     {
  263.         newspeed = speed - host_frametime * speed * sv_friction.value;
  264.         if (newspeed < 0)
  265.             newspeed = 0;  
  266.         VectorScale (velocity, newspeed/speed, velocity);
  267.     }
  268.     else
  269.         newspeed = 0;
  270.    
  271. //
  272. // water acceleration
  273. //
  274.     if (!wishspeed)
  275.         return;
  276.  
  277.     addspeed = wishspeed - newspeed;
  278.     if (addspeed <= 0)
  279.         return;
  280.  
  281.     VectorNormalize (wishvel);
  282.     accelspeed = sv_accelerate.value * wishspeed * host_frametime;
  283.     if (accelspeed > addspeed)
  284.         accelspeed = addspeed;
  285.  
  286.     for (i=0 ; i<3 ; i++)
  287.         velocity[i] += accelspeed * wishvel[i];
  288. }
  289.  
  290. void SV_WaterJump (void)
  291. {
  292.     if (sv.time > sv_player->v.teleport_time
  293.     || !sv_player->v.waterlevel)
  294.     {
  295.         sv_player->v.flags = (int)sv_player->v.flags & ~FL_WATERJUMP;
  296.         sv_player->v.teleport_time = 0;
  297.     }
  298.     sv_player->v.velocity[0] = sv_player->v.movedir[0];
  299.     sv_player->v.velocity[1] = sv_player->v.movedir[1];
  300. }
  301.  
  302.  
  303. /*
  304. ===================
  305. SV_AirMove
  306.  
  307. ===================
  308. */
  309. void SV_AirMove (void)
  310. {
  311.     int         i;
  312.     vec3_t      wishvel;
  313.     float       fmove, smove;
  314.  
  315.     AngleVectors (sv_player->v.angles, forward, right, up);
  316.  
  317.     fmove = cmd.forwardmove;
  318.     smove = cmd.sidemove;
  319.    
  320. // hack to not let you back into teleporter
  321.     if (sv.time < sv_player->v.teleport_time && fmove < 0)
  322.         fmove = 0;
  323.        
  324.     for (i=0 ; i<3 ; i++)
  325.         wishvel[i] = forward[i]*fmove + right[i]*smove;
  326.  
  327.     if ( (int)sv_player->v.movetype != MOVETYPE_WALK)
  328.         wishvel[2] = cmd.upmove;
  329.     else
  330.         wishvel[2] = 0;
  331.  
  332.     VectorCopy (wishvel, wishdir);
  333.     wishspeed = VectorNormalize(wishdir);
  334.     if (wishspeed > sv_maxspeed.value)
  335.     {
  336.         VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
  337.         wishspeed = sv_maxspeed.value;
  338.     }
  339.    
  340.     if ( sv_player->v.movetype == MOVETYPE_NOCLIP)
  341.     {   // noclip
  342.         VectorCopy (wishvel, velocity);
  343.     }
  344.     else if ( onground )
  345.     {
  346.         SV_UserFriction ();
  347.         SV_Accelerate ();
  348.     }
  349.     else
  350.     {   // not on ground, so little effect on velocity
  351.         SV_AirAccelerate (wishvel);
  352.     }      
  353. }
  354.  
  355. /*
  356. ===================
  357. SV_ClientThink
  358.  
  359. the move fields specify an intended velocity in pix/sec
  360. the angle fields specify an exact angular motion in degrees
  361. ===================
  362. */
  363. void SV_ClientThink (void)
  364. {
  365.     vec3_t      v_angle;
  366.  
  367.     if (sv_player->v.movetype == MOVETYPE_NONE)
  368.         return;
  369.    
  370.     onground = (int)sv_player->v.flags & FL_ONGROUND;
  371.  
  372.     origin = sv_player->v.origin;
  373.     velocity = sv_player->v.velocity;
  374.  
  375.     DropPunchAngle ();
  376.    
  377. //
  378. // if dead, behave differently
  379. //
  380.     if (sv_player->v.health <= 0)
  381.         return;
  382.  
  383. //
  384. // angles
  385. // show 1/3 the pitch angle and all the roll angle
  386.     cmd = host_client->cmd;
  387.     angles = sv_player->v.angles;
  388.    
  389.     VectorAdd (sv_player->v.v_angle, sv_player->v.punchangle, v_angle);
  390.     angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity)*4;
  391.     if (!sv_player->v.fixangle)
  392.     {
  393.         angles[PITCH] = -v_angle[PITCH]/3;
  394.         angles[YAW] = v_angle[YAW];
  395.     }
  396.  
  397.     if ( (int)sv_player->v.flags & FL_WATERJUMP )
  398.     {
  399.         SV_WaterJump ();
  400.         return;
  401.     }
  402. //
  403. // walk
  404. //
  405.     if ( (sv_player->v.waterlevel >= 2)
  406.     && (sv_player->v.movetype != MOVETYPE_NOCLIP) )
  407.     {
  408.         SV_WaterMove ();
  409.         return;
  410.     }
  411.  
  412.     SV_AirMove (); 
  413. }
  414.  
  415.  
  416. /*
  417. ===================
  418. SV_ReadClientMove
  419. ===================
  420. */
  421. void SV_ReadClientMove (usercmd_t *move)
  422. {
  423.     int     i;
  424.     vec3_t  angle;
  425.     int     bits;
  426.    
  427. // read ping time
  428.     host_client->ping_times[host_client->num_pings%NUM_PING_TIMES]
  429.         = sv.time - MSG_ReadFloat ();
  430.     host_client->num_pings++;
  431.  
  432. // read current angles 
  433.     for (i=0 ; i<3 ; i++)
  434.         angle[i] = MSG_ReadAngle ();
  435.  
  436.     VectorCopy (angle, host_client->edict->v.v_angle);
  437.        
  438. // read movement
  439.     move->forwardmove = MSG_ReadShort ();
  440.     move->sidemove = MSG_ReadShort ();
  441.     move->upmove = MSG_ReadShort ();
  442.    
  443. // read buttons
  444.     bits = MSG_ReadByte ();
  445.     host_client->edict->v.button0 = bits & 1;
  446.     host_client->edict->v.button2 = (bits & 2)>>1;
  447.  
  448.     i = MSG_ReadByte ();
  449.     if (i)
  450.         host_client->edict->v.impulse = i;
  451.  
  452. #ifdef QUAKE2
  453. // read light level
  454.     host_client->edict->v.light_level = MSG_ReadByte ();
  455. #endif
  456. }
  457.  
  458. /*
  459. ===================
  460. SV_ReadClientMessage
  461.  
  462. Returns false if the client should be killed
  463. ===================
  464. */
  465. qboolean SV_ReadClientMessage (void)
  466. {
  467.     int     ret;
  468.     int     cmd;
  469.     char        *s;
  470.    
  471.     do
  472.     {
  473. nextmsg:
  474.         ret = NET_GetMessage (host_client->netconnection);
  475.         if (ret == -1)
  476.         {
  477.             Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
  478.             return false;
  479.         }
  480.         if (!ret)
  481.             return true;
  482.                    
  483.         MSG_BeginReading ();
  484.        
  485.         while (1)
  486.         {
  487.             if (!host_client->active)
  488.                 return false;   // a command caused an error
  489.  
  490.             if (msg_badread)
  491.             {
  492.                 Sys_Printf ("SV_ReadClientMessage: badread\n");
  493.                 return false;
  494.             }  
  495.    
  496.             cmd = MSG_ReadChar ();
  497.            
  498.             switch (cmd)
  499.             {
  500.             case -1:
  501.                 goto nextmsg;       // end of message
  502.                
  503.             default:
  504.                 Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
  505.                 return false;
  506.                            
  507.             case clc_nop:
  508. //              Sys_Printf ("clc_nop\n");
  509.                 break;
  510.                
  511.             case clc_stringcmd:
  512.                 s = MSG_ReadString ();
  513.                 if (host_client->privileged)
  514.                     ret = 2;
  515.                 else
  516.                     ret = 0;
  517.                 if (Q_strncasecmp(s, "status", 6) == 0)
  518.                     ret = 1;
  519.                 else if (Q_strncasecmp(s, "xx", 2) == 0)
  520.                     ret = 1;
  521.                 else if (Q_strncasecmp(s, "notarget", 8) == 0)
  522.                     ret = 1;
  523.                 else if (Q_strncasecmp(s, "fly", 3) == 0)
  524.                     ret = 1;
  525.                 else if (Q_strncasecmp(s, "name", 4) == 0)
  526.                     ret = 1;
  527.                 else if (Q_strncasecmp(s, "noclip", 6) == 0)
  528.                     ret = 1;
  529.                 else if (Q_strncasecmp(s, "---", 3) == 0)
  530.                     ret = 1;
  531.                 else if (Q_strncasecmp(s, "say_team", 8) == 0)
  532.                     ret = 1;
  533.                 else if (Q_strncasecmp(s, "tell", 4) == 0)
  534.                     ret = 1;
  535.                 else if (Q_strncasecmp(s, "color", 5) == 0)
  536.                     ret = 1;
  537.                 else if (Q_strncasecmp(s, "kill", 4) == 0)
  538.                     ret = 1;
  539.                 else if (Q_strncasecmp(s, "pause", 5) == 0)
  540.                     ret = 1;
  541.                 else if (Q_strncasecmp(s, "spawn", 5) == 0)
  542.                     ret = 1;
  543.                 else if (Q_strncasecmp(s, "begin", 5) == 0)
  544.                     ret = 1;
  545.                 else if (Q_strncasecmp(s, "prespawn", 8) == 0)
  546.                     ret = 1;
  547.                 else if (Q_strncasecmp(s, "kick", 4) == 0)
  548.                     ret = 1;
  549.                 else if (Q_strncasecmp(s, "ping", 4) == 0)
  550.                     ret = 1;
  551.                 else if (Q_strncasecmp(s, "give", 4) == 0)
  552.                     ret = 1;
  553.                 else if (Q_strncasecmp(s, "ban", 3) == 0)
  554.                     ret = 1;
  555.                 if (ret == 2)
  556.                     Cbuf_InsertText (s);
  557.                 else if (ret == 1)
  558.                     Cmd_ExecuteString (s, src_client);
  559.                 else
  560.                     Con_DPrintf("%s tried to %s\n", host_client->name, s);
  561.                 break;
  562.                
  563.             case clc_disconnect:
  564. //              Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
  565.                 return false;
  566.            
  567.             case clc_move:
  568.                 SV_ReadClientMove (&host_client->cmd);
  569.                 break;
  570.             }
  571.         }
  572.     } while (ret == 1);
  573.    
  574.     return true;
  575. }
  576.  
  577.  
  578. /*
  579. ==================
  580. SV_RunClients
  581. ==================
  582. */
  583. void SV_RunClients (void)
  584. {
  585.     int             i;
  586.    
  587.     for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
  588.     {
  589.         if (!host_client->active)
  590.             continue;
  591.    
  592.         sv_player = host_client->edict;
  593.  
  594.         if (!SV_ReadClientMessage ())
  595.         {
  596.             SV_DropClient (false);  // client misbehaved...
  597.             continue;
  598.         }
  599.  
  600.         if (!host_client->spawned)
  601.         {
  602.         // clear client movement until a new packet is received
  603.             memset (&host_client->cmd, 0, sizeof(host_client->cmd));
  604.             continue;
  605.         }
  606.  
  607. // always pause in single player if in console or menus
  608.         if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
  609.             SV_ClientThink ();
  610.     }
  611. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement