Annotation of quake1/sv_user.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.