home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / sv_user.c < prev    next >
C/C++ Source or Header  |  1999-12-28  |  14KB  |  630 lines

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