Annotation of quake2/qcommon/pmove.c, revision 1.1.1.2

1.1       root        1: 
                      2: #include "qcommon.h"
                      3: 
1.1.1.2 ! root        4: 
        !             5: 
1.1       root        6: #define        STEPSIZE        18
                      7: 
                      8: // all of the locals will be zeroed before each
                      9: // pmove, just to make damn sure we don't have
                     10: // any differences when running on client or server
                     11: 
                     12: typedef struct
                     13: {
                     14:        vec3_t          origin;                 // full float precision
                     15:        vec3_t          velocity;               // full float precision
                     16: 
                     17:        vec3_t          forward, right, up;
                     18:        float           frametime;
                     19: 
                     20: 
                     21:        csurface_t      *groundsurface;
                     22:        cplane_t        groundplane;
                     23:        int                     groundcontents;
                     24: 
                     25:        vec3_t          previous_origin;
                     26:        qboolean        ladder;
                     27: } pml_t;
                     28: 
                     29: pmove_t                *pm;
                     30: pml_t          pml;
                     31: 
1.1.1.2 ! root       32: 
1.1       root       33: // movement parameters
                     34: float  pm_stopspeed = 100;
                     35: float  pm_maxspeed = 300;
                     36: float  pm_duckspeed = 100;
                     37: float  pm_accelerate = 10;
                     38: float  pm_airaccelerate = 1;
                     39: float  pm_wateraccelerate = 10;
                     40: float  pm_friction = 6;
                     41: float  pm_waterfriction = 1;
                     42: float  pm_waterspeed = 400;
1.1.1.2 ! root       43: 
1.1       root       44: /*
1.1.1.2 ! root       45: 
1.1       root       46:   walking up a step should kill some velocity
1.1.1.2 ! root       47: 
1.1       root       48: */
1.1.1.2 ! root       49: 
        !            50: 
1.1       root       51: /*
                     52: ==================
                     53: PM_ClipVelocity
1.1.1.2 ! root       54: 
1.1       root       55: Slide off of the impacting object
                     56: returns the blocked flags (1 = floor, 2 = step / wall)
                     57: ==================
                     58: */
                     59: #define        STOP_EPSILON    0.1
1.1.1.2 ! root       60: 
1.1       root       61: void PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
                     62: {
                     63:        float   backoff;
                     64:        float   change;
                     65:        int             i;
                     66:        
                     67:        backoff = DotProduct (in, normal) * overbounce;
1.1.1.2 ! root       68: 
1.1       root       69:        for (i=0 ; i<3 ; i++)
                     70:        {
                     71:                change = normal[i]*backoff;
                     72:                out[i] = in[i] - change;
                     73:                if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
                     74:                        out[i] = 0;
                     75:        }
                     76: }
1.1.1.2 ! root       77: 
        !            78: 
        !            79: 
        !            80: 
1.1       root       81: /*
                     82: ==================
                     83: PM_StepSlideMove
1.1.1.2 ! root       84: 
1.1       root       85: Each intersection will try to step over the obstruction instead of
                     86: sliding along it.
1.1.1.2 ! root       87: 
1.1       root       88: Returns a new origin, velocity, and contact entity
                     89: Does not modify any world state?
                     90: ==================
                     91: */
                     92: #define        MIN_STEP_NORMAL 0.7             // can't step up onto very steep slopes
                     93: #define        MAX_CLIP_PLANES 5
                     94: void PM_StepSlideMove_ (void)
                     95: {
                     96:        int                     bumpcount, numbumps;
                     97:        vec3_t          dir;
1.1.1.2 ! root       98:        float           d;
1.1       root       99:        int                     numplanes;
                    100:        vec3_t          planes[MAX_CLIP_PLANES];
                    101:        vec3_t          primal_velocity;
1.1.1.2 ! root      102:        int                     i, j;
1.1       root      103:        trace_t trace;
                    104:        vec3_t          end;
                    105:        float           time_left;
                    106:        
                    107:        numbumps = 4;
                    108:        
                    109:        VectorCopy (pml.velocity, primal_velocity);
                    110:        numplanes = 0;
                    111:        
                    112:        time_left = pml.frametime;
1.1.1.2 ! root      113: 
1.1       root      114:        for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
                    115:        {
                    116:                for (i=0 ; i<3 ; i++)
                    117:                        end[i] = pml.origin[i] + time_left * pml.velocity[i];
1.1.1.2 ! root      118: 
1.1       root      119:                trace = pm->trace (pml.origin, pm->mins, pm->maxs, end);
1.1.1.2 ! root      120: 
1.1       root      121:                if (trace.allsolid)
                    122:                {       // entity is trapped in another solid
                    123:                        pml.velocity[2] = 0;    // don't build up falling damage
                    124:                        return;
                    125:                }
1.1.1.2 ! root      126: 
1.1       root      127:                if (trace.fraction > 0)
                    128:                {       // actually covered some distance
                    129:                        VectorCopy (trace.endpos, pml.origin);
                    130:                        numplanes = 0;
                    131:                }
1.1.1.2 ! root      132: 
1.1       root      133:                if (trace.fraction == 1)
                    134:                         break;         // moved the entire distance
1.1.1.2 ! root      135: 
1.1       root      136:                // save entity for contact
                    137:                if (pm->numtouch < MAXTOUCH && trace.ent)
                    138:                {
                    139:                        pm->touchents[pm->numtouch] = trace.ent;
                    140:                        pm->numtouch++;
                    141:                }
                    142:                
                    143:                time_left -= time_left * trace.fraction;
1.1.1.2 ! root      144: 
1.1       root      145:                // slide along this plane
                    146:                if (numplanes >= MAX_CLIP_PLANES)
                    147:                {       // this shouldn't really happen
                    148:                        VectorCopy (vec3_origin, pml.velocity);
                    149:                        break;
                    150:                }
1.1.1.2 ! root      151: 
1.1       root      152:                VectorCopy (trace.plane.normal, planes[numplanes]);
                    153:                numplanes++;
1.1.1.2 ! root      154: 
        !           155: #if 0
        !           156:        float           rub;
        !           157: 
1.1       root      158:                //
                    159:                // modify velocity so it parallels all of the clip planes
                    160:                //
                    161:                if (numplanes == 1)
                    162:                {       // go along this plane
                    163:                        VectorCopy (pml.velocity, dir);
                    164:                        VectorNormalize (dir);
                    165:                        rub = 1.0 + 0.5 * DotProduct (dir, planes[0]);
                    166: 
                    167:                        // slide along the plane
                    168:                        PM_ClipVelocity (pml.velocity, planes[0], pml.velocity, 1.01);
                    169:                        // rub some extra speed off on xy axis
                    170:                        // not on Z, or you can scrub down walls
                    171:                        pml.velocity[0] *= rub;
                    172:                        pml.velocity[1] *= rub;
                    173:                        pml.velocity[2] *= rub;
                    174:                }
                    175:                else if (numplanes == 2)
                    176:                {       // go along the crease
                    177:                        VectorCopy (pml.velocity, dir);
                    178:                        VectorNormalize (dir);
                    179:                        rub = 1.0 + 0.5 * DotProduct (dir, planes[0]);
                    180: 
                    181:                        // slide along the plane
                    182:                        CrossProduct (planes[0], planes[1], dir);
                    183:                        d = DotProduct (dir, pml.velocity);
                    184:                        VectorScale (dir, d, pml.velocity);
1.1.1.2 ! root      185: 
1.1       root      186:                        // rub some extra speed off
                    187:                        VectorScale (pml.velocity, rub, pml.velocity);
                    188:                }
                    189:                else
                    190:                {
                    191: //                     Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
                    192:                        VectorCopy (vec3_origin, pml.velocity);
                    193:                        break;
                    194:                }
1.1.1.2 ! root      195: 
        !           196: #else
        !           197: //
        !           198: // modify original_velocity so it parallels all of the clip planes
        !           199: //
        !           200:                for (i=0 ; i<numplanes ; i++)
        !           201:                {
        !           202:                        PM_ClipVelocity (pml.velocity, planes[i], pml.velocity, 1.01);
        !           203:                        for (j=0 ; j<numplanes ; j++)
        !           204:                                if (j != i)
        !           205:                                {
        !           206:                                        if (DotProduct (pml.velocity, planes[j]) < 0)
        !           207:                                                break;  // not ok
        !           208:                                }
        !           209:                        if (j == numplanes)
        !           210:                                break;
        !           211:                }
        !           212:                
        !           213:                if (i != numplanes)
        !           214:                {       // go along this plane
        !           215:                }
        !           216:                else
        !           217:                {       // go along the crease
        !           218:                        if (numplanes != 2)
        !           219:                        {
        !           220: //                             Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
        !           221:                                VectorCopy (vec3_origin, pml.velocity);
        !           222:                                break;
        !           223:                        }
        !           224:                        CrossProduct (planes[0], planes[1], dir);
        !           225:                        d = DotProduct (dir, pml.velocity);
        !           226:                        VectorScale (dir, d, pml.velocity);
        !           227:                }
        !           228: #endif
1.1       root      229:                //
                    230:                // if velocity is against the original velocity, stop dead
                    231:                // to avoid tiny occilations in sloping corners
                    232:                //
                    233:                if (DotProduct (pml.velocity, primal_velocity) <= 0)
                    234:                {
                    235:                        VectorCopy (vec3_origin, pml.velocity);
                    236:                        break;
                    237:                }
                    238:        }
1.1.1.2 ! root      239: 
1.1       root      240:        if (pm->s.pm_time)
                    241:        {
                    242:                VectorCopy (primal_velocity, pml.velocity);
                    243:        }
                    244: }
                    245: 
                    246: /*
                    247: ==================
                    248: PM_StepSlideMove
                    249: 
                    250: ==================
                    251: */
                    252: void PM_StepSlideMove (void)
                    253: {
                    254:        vec3_t          start_o, start_v;
                    255:        vec3_t          down_o, down_v;
                    256:        trace_t         trace;
                    257:        float           down_dist, up_dist;
1.1.1.2 ! root      258: //     vec3_t          delta;
1.1       root      259:        vec3_t          up, down;
                    260: 
                    261:        VectorCopy (pml.origin, start_o);
                    262:        VectorCopy (pml.velocity, start_v);
                    263: 
                    264:        PM_StepSlideMove_ ();
                    265: 
                    266:        VectorCopy (pml.origin, down_o);
                    267:        VectorCopy (pml.velocity, down_v);
                    268: 
                    269:        VectorCopy (start_o, up);
                    270:        up[2] += STEPSIZE;
                    271: 
                    272:        trace = pm->trace (up, pm->mins, pm->maxs, up);
                    273:        if (trace.allsolid)
                    274:                return;         // can't step up
                    275: 
                    276:        // try sliding above
                    277:        VectorCopy (up, pml.origin);
                    278:        VectorCopy (start_v, pml.velocity);
                    279: 
                    280:        PM_StepSlideMove_ ();
                    281: 
                    282:        // push down the final amount
                    283:        VectorCopy (pml.origin, down);
                    284:        down[2] -= STEPSIZE;
                    285:        trace = pm->trace (pml.origin, pm->mins, pm->maxs, down);
                    286:        if (!trace.allsolid)
                    287:        {
                    288:                VectorCopy (trace.endpos, pml.origin);
                    289:        }
                    290: 
1.1.1.2 ! root      291: #if 0
1.1       root      292:        VectorSubtract (pml.origin, up, delta);
                    293:        up_dist = DotProduct (delta, start_v);
                    294: 
                    295:        VectorSubtract (down_o, start_o, delta);
                    296:        down_dist = DotProduct (delta, start_v);
1.1.1.2 ! root      297: #else
        !           298:        VectorCopy(pml.origin, up);
        !           299: 
        !           300:        // decide which one went farther
        !           301:     down_dist = (down_o[0] - start_o[0])*(down_o[0] - start_o[0])
        !           302:         + (down_o[1] - start_o[1])*(down_o[1] - start_o[1]);
        !           303:     up_dist = (up[0] - start_o[0])*(up[0] - start_o[0])
        !           304:         + (up[1] - start_o[1])*(up[1] - start_o[1]);
        !           305: #endif
1.1       root      306: 
                    307:        if (down_dist > up_dist || trace.plane.normal[2] < MIN_STEP_NORMAL)
                    308:        {
                    309:                VectorCopy (down_o, pml.origin);
                    310:                VectorCopy (down_v, pml.velocity);
                    311:                return;
                    312:        }
1.1.1.2 ! root      313:        //!! Special case
        !           314:        // if we were walking along a plane, then we need to copy the Z over
        !           315:        pml.velocity[2] = down_v[2];
1.1       root      316: }
                    317: 
1.1.1.2 ! root      318: 
1.1       root      319: /*
                    320: ==================
                    321: PM_Friction
1.1.1.2 ! root      322: 
1.1       root      323: Handles both ground friction and water friction
                    324: ==================
                    325: */
                    326: void PM_Friction (void)
                    327: {
                    328:        float   *vel;
                    329:        float   speed, newspeed, control;
                    330:        float   friction;
                    331:        float   drop;
                    332:        
                    333:        vel = pml.velocity;
                    334:        
                    335:        speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]);
                    336:        if (speed < 1)
                    337:        {
                    338:                vel[0] = 0;
                    339:                vel[1] = 0;
                    340:                return;
                    341:        }
1.1.1.2 ! root      342: 
1.1       root      343:        drop = 0;
1.1.1.2 ! root      344: 
1.1       root      345: // apply ground friction
                    346:        if ((pm->groundentity && pml.groundsurface && !(pml.groundsurface->flags & SURF_SLICK) ) || (pml.ladder) )
                    347:        {
                    348:                friction = pm_friction;
                    349:                control = speed < pm_stopspeed ? pm_stopspeed : speed;
                    350:                drop += control*friction*pml.frametime;
                    351:        }
1.1.1.2 ! root      352: 
1.1       root      353: // apply water friction
1.1.1.2 ! root      354:        if (pm->waterlevel >= 2 && !pml.ladder)
1.1       root      355:                drop += speed*pm_waterfriction*pm->waterlevel*pml.frametime;
1.1.1.2 ! root      356: 
1.1       root      357: // scale the velocity
                    358:        newspeed = speed - drop;
                    359:        if (newspeed < 0)
                    360:        {
                    361:                newspeed = 0;
                    362:        }
                    363:        newspeed /= speed;
1.1.1.2 ! root      364: 
1.1       root      365:        vel[0] = vel[0] * newspeed;
                    366:        vel[1] = vel[1] * newspeed;
                    367:        vel[2] = vel[2] * newspeed;
                    368: }
1.1.1.2 ! root      369: 
        !           370: 
1.1       root      371: /*
                    372: ==============
                    373: PM_Accelerate
1.1.1.2 ! root      374: 
1.1       root      375: Handles user intended acceleration
                    376: ==============
                    377: */
                    378: void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel)
                    379: {
                    380:        int                     i;
                    381:        float           addspeed, accelspeed, currentspeed;
                    382: 
                    383:        currentspeed = DotProduct (pml.velocity, wishdir);
                    384:        addspeed = wishspeed - currentspeed;
                    385:        if (addspeed <= 0)
                    386:                return;
                    387:        accelspeed = accel*pml.frametime*wishspeed;
                    388:        if (accelspeed > addspeed)
                    389:                accelspeed = addspeed;
                    390:        
                    391:        for (i=0 ; i<3 ; i++)
                    392:                pml.velocity[i] += accelspeed*wishdir[i];       
                    393: }
1.1.1.2 ! root      394: 
        !           395: void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel)
        !           396: {
        !           397:        int                     i;
        !           398:        float           addspeed, accelspeed, currentspeed, wishspd = wishspeed;
        !           399:                
        !           400:        if (wishspd > 30)
        !           401:                wishspd = 30;
        !           402:        currentspeed = DotProduct (pml.velocity, wishdir);
        !           403:        addspeed = wishspd - currentspeed;
        !           404:        if (addspeed <= 0)
        !           405:                return;
        !           406:        accelspeed = accel * wishspeed * pml.frametime;
        !           407:        if (accelspeed > addspeed)
        !           408:                accelspeed = addspeed;
        !           409:        
        !           410:        for (i=0 ; i<3 ; i++)
        !           411:                pml.velocity[i] += accelspeed*wishdir[i];       
        !           412: }
        !           413: 
1.1       root      414: /*
                    415: =============
                    416: PM_AddCurrents
                    417: =============
                    418: */
                    419: void PM_AddCurrents (vec3_t    wishvel)
                    420: {
                    421:        vec3_t  v;
                    422:        float   s;
1.1.1.2 ! root      423: 
1.1       root      424:        //
                    425:        // account for ladders
                    426:        //
1.1.1.2 ! root      427: 
1.1       root      428:        if (pml.ladder && fabs(pml.velocity[2]) <= 200)
                    429:        {
                    430:                if ((pm->viewangles[PITCH] <= -15) && (pm->cmd.forwardmove > 0))
                    431:                        wishvel[2] = 200;
                    432:                else if ((pm->viewangles[PITCH] >= 15) && (pm->cmd.forwardmove > 0))
                    433:                        wishvel[2] = -200;
                    434:                else if (pm->cmd.upmove > 0)
                    435:                        wishvel[2] = 200;
                    436:                else if (pm->cmd.upmove < 0)
                    437:                        wishvel[2] = -200;
                    438:                else
                    439:                        wishvel[2] = 0;
1.1.1.2 ! root      440: 
1.1       root      441:                // limit horizontal speed when on a ladder
                    442:                if (wishvel[0] < -25)
                    443:                        wishvel[0] = -25;
                    444:                else if (wishvel[0] > 25)
                    445:                        wishvel[0] = 25;
1.1.1.2 ! root      446: 
1.1       root      447:                if (wishvel[1] < -25)
                    448:                        wishvel[1] = -25;
                    449:                else if (wishvel[1] > 25)
                    450:                        wishvel[1] = 25;
                    451:        }
1.1.1.2 ! root      452: 
        !           453: 
1.1       root      454:        //
                    455:        // add water currents
                    456:        //
1.1.1.2 ! root      457: 
1.1       root      458:        if (pm->watertype & MASK_CURRENT)
                    459:        {
                    460:                VectorClear (v);
1.1.1.2 ! root      461: 
1.1       root      462:                if (pm->watertype & CONTENTS_CURRENT_0)
                    463:                        v[0] += 1;
                    464:                if (pm->watertype & CONTENTS_CURRENT_90)
                    465:                        v[1] += 1;
                    466:                if (pm->watertype & CONTENTS_CURRENT_180)
                    467:                        v[0] -= 1;
                    468:                if (pm->watertype & CONTENTS_CURRENT_270)
                    469:                        v[1] -= 1;
                    470:                if (pm->watertype & CONTENTS_CURRENT_UP)
                    471:                        v[2] += 1;
                    472:                if (pm->watertype & CONTENTS_CURRENT_DOWN)
                    473:                        v[2] -= 1;
1.1.1.2 ! root      474: 
1.1       root      475:                s = pm_waterspeed;
                    476:                if ((pm->waterlevel == 1) && (pm->groundentity))
                    477:                        s /= 2;
1.1.1.2 ! root      478: 
1.1       root      479:                VectorMA (wishvel, s, v, wishvel);
                    480:        }
1.1.1.2 ! root      481: 
1.1       root      482:        //
                    483:        // add conveyor belt velocities
                    484:        //
1.1.1.2 ! root      485: 
1.1       root      486:        if (pm->groundentity)
                    487:        {
                    488:                VectorClear (v);
1.1.1.2 ! root      489: 
1.1       root      490:                if (pml.groundcontents & CONTENTS_CURRENT_0)
                    491:                        v[0] += 1;
                    492:                if (pml.groundcontents & CONTENTS_CURRENT_90)
                    493:                        v[1] += 1;
                    494:                if (pml.groundcontents & CONTENTS_CURRENT_180)
                    495:                        v[0] -= 1;
                    496:                if (pml.groundcontents & CONTENTS_CURRENT_270)
                    497:                        v[1] -= 1;
                    498:                if (pml.groundcontents & CONTENTS_CURRENT_UP)
                    499:                        v[2] += 1;
                    500:                if (pml.groundcontents & CONTENTS_CURRENT_DOWN)
                    501:                        v[2] -= 1;
                    502: 
                    503:                VectorMA (wishvel, 100 /* pm->groundentity->speed */, v, wishvel);
                    504:        }
                    505: }
1.1.1.2 ! root      506: 
        !           507: 
1.1       root      508: /*
                    509: ===================
                    510: PM_WaterMove
1.1.1.2 ! root      511: 
1.1       root      512: ===================
                    513: */
                    514: void PM_WaterMove (void)
                    515: {
                    516:        int             i;
                    517:        vec3_t  wishvel;
                    518:        float   wishspeed;
                    519:        vec3_t  wishdir;
1.1.1.2 ! root      520: 
1.1       root      521: //
                    522: // user intentions
                    523: //
                    524:        for (i=0 ; i<3 ; i++)
                    525:                wishvel[i] = pml.forward[i]*pm->cmd.forwardmove + pml.right[i]*pm->cmd.sidemove;
1.1.1.2 ! root      526: 
1.1       root      527:        if (!pm->cmd.forwardmove && !pm->cmd.sidemove && !pm->cmd.upmove)
                    528:                wishvel[2] -= 60;               // drift towards bottom
                    529:        else
                    530:                wishvel[2] += pm->cmd.upmove;
1.1.1.2 ! root      531: 
1.1       root      532:        PM_AddCurrents (wishvel);
1.1.1.2 ! root      533: 
1.1       root      534:        VectorCopy (wishvel, wishdir);
                    535:        wishspeed = VectorNormalize(wishdir);
1.1.1.2 ! root      536: 
1.1       root      537:        if (wishspeed > pm_maxspeed)
                    538:        {
                    539:                VectorScale (wishvel, pm_maxspeed/wishspeed, wishvel);
                    540:                wishspeed = pm_maxspeed;
                    541:        }
                    542:        wishspeed *= 0.5;
1.1.1.2 ! root      543: 
1.1       root      544:        PM_Accelerate (wishdir, wishspeed, pm_wateraccelerate);
1.1.1.2 ! root      545: 
1.1       root      546:        PM_StepSlideMove ();
                    547: }
1.1.1.2 ! root      548: 
        !           549: 
1.1       root      550: /*
                    551: ===================
                    552: PM_AirMove
1.1.1.2 ! root      553: 
1.1       root      554: ===================
                    555: */
                    556: void PM_AirMove (void)
                    557: {
                    558:        int                     i;
                    559:        vec3_t          wishvel;
                    560:        float           fmove, smove;
                    561:        vec3_t          wishdir;
                    562:        float           wishspeed;
                    563:        float           maxspeed;
1.1.1.2 ! root      564: 
1.1       root      565:        fmove = pm->cmd.forwardmove;
                    566:        smove = pm->cmd.sidemove;
                    567:        
1.1.1.2 ! root      568: //!!!!! pitch should be 1/3 so this isn't needed??!
        !           569: #if 0
1.1       root      570:        pml.forward[2] = 0;
                    571:        pml.right[2] = 0;
                    572:        VectorNormalize (pml.forward);
                    573:        VectorNormalize (pml.right);
1.1.1.2 ! root      574: #endif
        !           575: 
1.1       root      576:        for (i=0 ; i<2 ; i++)
                    577:                wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
                    578:        wishvel[2] = 0;
1.1.1.2 ! root      579: 
1.1       root      580:        PM_AddCurrents (wishvel);
1.1.1.2 ! root      581: 
1.1       root      582:        VectorCopy (wishvel, wishdir);
                    583:        wishspeed = VectorNormalize(wishdir);
1.1.1.2 ! root      584: 
1.1       root      585: //
                    586: // clamp to server defined max speed
                    587: //
                    588:        maxspeed = (pm->s.pm_flags & PMF_DUCKED) ? pm_duckspeed : pm_maxspeed;
1.1.1.2 ! root      589: 
1.1       root      590:        if (wishspeed > maxspeed)
                    591:        {
                    592:                VectorScale (wishvel, maxspeed/wishspeed, wishvel);
                    593:                wishspeed = maxspeed;
                    594:        }
                    595:        
                    596:        if ( pml.ladder )
                    597:        {
                    598:                PM_Accelerate (wishdir, wishspeed, pm_accelerate);
                    599:                if (!wishvel[2])
                    600:                {
                    601:                        if (pml.velocity[2] > 0)
                    602:                        {
                    603:                                pml.velocity[2] -= pm->s.gravity * pml.frametime;
                    604:                                if (pml.velocity[2] < 0)
                    605:                                        pml.velocity[2]  = 0;
                    606:                        }
                    607:                        else
                    608:                        {
                    609:                                pml.velocity[2] += pm->s.gravity * pml.frametime;
                    610:                                if (pml.velocity[2] > 0)
                    611:                                        pml.velocity[2]  = 0;
                    612:                        }
                    613:                }
                    614:                PM_StepSlideMove ();
                    615:        }
                    616:        else if ( pm->groundentity )
                    617:        {       // walking on ground
1.1.1.2 ! root      618:                pml.velocity[2] = 0; //!!! this is before the accel
1.1       root      619:                PM_Accelerate (wishdir, wishspeed, pm_accelerate);
1.1.1.2 ! root      620:                pml.velocity[2] -= pm->s.gravity * pml.frametime;
1.1       root      621:                if (!pml.velocity[0] && !pml.velocity[1])
                    622:                        return;
                    623:                PM_StepSlideMove ();
                    624:        }
                    625:        else
                    626:        {       // not on ground, so little effect on velocity
1.1.1.2 ! root      627: #if 0 // ZOID:  Air control removed
        !           628:                PM_AirAccelerate (wishdir, wishspeed, pm_accelerate);
        !           629: #else
1.1       root      630:                PM_Accelerate (wishdir, wishspeed, pm_airaccelerate);
1.1.1.2 ! root      631: #endif
1.1       root      632:                // add gravity
                    633:                pml.velocity[2] -= pm->s.gravity * pml.frametime;
                    634:                PM_StepSlideMove ();
                    635:        }
                    636: }
1.1.1.2 ! root      637: 
        !           638: 
        !           639: 
1.1       root      640: /*
                    641: =============
                    642: PM_CatagorizePosition
                    643: =============
                    644: */
                    645: void PM_CatagorizePosition (void)
                    646: {
                    647:        vec3_t          point;
                    648:        int                     cont;
                    649:        trace_t         trace;
                    650:        int                     sample1;
                    651:        int                     sample2;
1.1.1.2 ! root      652: 
1.1       root      653: // if the player hull point one unit down is solid, the player
                    654: // is on ground
1.1.1.2 ! root      655: 
1.1       root      656: // see if standing on something solid  
                    657:        point[0] = pml.origin[0];
                    658:        point[1] = pml.origin[1];
                    659:        point[2] = pml.origin[2] - 0.25;
1.1.1.2 ! root      660:        if (pml.velocity[2] > 180) //!!ZOID changed from 100 to 180 (ramp accel)
1.1       root      661:        {
                    662:                pm->s.pm_flags &= ~PMF_ON_GROUND;
                    663:                pm->groundentity = NULL;
                    664:        }
                    665:        else
                    666:        {
                    667:                trace = pm->trace (pml.origin, pm->mins, pm->maxs, point);
                    668:                pml.groundplane = trace.plane;
                    669:                pml.groundsurface = trace.surface;
                    670:                pml.groundcontents = trace.contents;
                    671: 
                    672:                if (!trace.ent || (trace.plane.normal[2] < 0.7 && !trace.startsolid) )
                    673:                {
                    674:                        pm->groundentity = NULL;
                    675:                        pm->s.pm_flags &= ~PMF_ON_GROUND;
                    676:                }
                    677:                else
                    678:                {
                    679:                        pm->groundentity = trace.ent;
                    680: 
                    681:                        // hitting solid ground will end a waterjump
                    682:                        if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
                    683:                        {
                    684:                                pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                    685:                                pm->s.pm_time = 0;
                    686:                        }
                    687: 
                    688:                        if (! (pm->s.pm_flags & PMF_ON_GROUND) )
                    689:                        {       // just hit the ground
                    690:                                pm->s.pm_flags |= PMF_ON_GROUND;
                    691:                                // don't do landing time if we were just going down a slope
                    692:                                if (pml.velocity[2] < -200)
                    693:                                {
                    694:                                        pm->s.pm_flags |= PMF_TIME_LAND;
                    695:                                        // don't allow another jump for a little while
                    696:                                        if (pml.velocity[2] < -400)
                    697:                                                pm->s.pm_time = 25;     
                    698:                                        else
                    699:                                                pm->s.pm_time = 18;
                    700:                                }
                    701:                        }
                    702:                }
1.1.1.2 ! root      703: 
        !           704: #if 0
1.1       root      705:                if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0)
                    706:                        pml.velocity[2] = 0;
1.1.1.2 ! root      707: #endif
1.1       root      708: 
                    709:                if (pm->numtouch < MAXTOUCH && trace.ent)
                    710:                {
                    711:                        pm->touchents[pm->numtouch] = trace.ent;
                    712:                        pm->numtouch++;
                    713:                }
                    714:        }
1.1.1.2 ! root      715: 
1.1       root      716: //
                    717: // get waterlevel, accounting for ducking
                    718: //
                    719:        pm->waterlevel = 0;
                    720:        pm->watertype = 0;
1.1.1.2 ! root      721: 
1.1       root      722:        sample2 = pm->viewheight - pm->mins[2];
                    723:        sample1 = sample2 / 2;
1.1.1.2 ! root      724: 
1.1       root      725:        point[2] = pml.origin[2] + pm->mins[2] + 1;     
                    726:        cont = pm->pointcontents (point);
1.1.1.2 ! root      727: 
1.1       root      728:        if (cont & MASK_WATER)
                    729:        {
                    730:                pm->watertype = cont;
                    731:                pm->waterlevel = 1;
                    732:                point[2] = pml.origin[2] + pm->mins[2] + sample1;
                    733:                cont = pm->pointcontents (point);
                    734:                if (cont & MASK_WATER)
                    735:                {
                    736:                        pm->waterlevel = 2;
                    737:                        point[2] = pml.origin[2] + pm->mins[2] + sample2;
                    738:                        cont = pm->pointcontents (point);
                    739:                        if (cont & MASK_WATER)
                    740:                                pm->waterlevel = 3;
                    741:                }
                    742:        }
1.1.1.2 ! root      743: 
1.1       root      744: }
1.1.1.2 ! root      745: 
        !           746: 
1.1       root      747: /*
                    748: =============
                    749: PM_CheckJump
                    750: =============
                    751: */
                    752: void PM_CheckJump (void)
                    753: {
                    754:        if (pm->s.pm_flags & PMF_TIME_LAND)
                    755:        {       // hasn't been long enough since landing to jump again
                    756:                return;
                    757:        }
1.1.1.2 ! root      758: 
1.1       root      759:        if (pm->cmd.upmove < 10)
                    760:        {       // not holding jump
                    761:                pm->s.pm_flags &= ~PMF_JUMP_HELD;
                    762:                return;
                    763:        }
                    764: 
                    765:        // must wait for jump to be released
                    766:        if (pm->s.pm_flags & PMF_JUMP_HELD)
                    767:                return;
                    768: 
                    769:        if (pm->s.pm_type == PM_DEAD)
                    770:                return;
1.1.1.2 ! root      771: 
1.1       root      772:        if (pm->waterlevel >= 2)
                    773:        {       // swimming, not jumping
                    774:                pm->groundentity = NULL;
1.1.1.2 ! root      775: 
1.1       root      776:                if (pml.velocity[2] <= -300)
                    777:                        return;
                    778: 
                    779:                if (pm->watertype == CONTENTS_WATER)
                    780:                        pml.velocity[2] = 100;
                    781:                else if (pm->watertype == CONTENTS_SLIME)
                    782:                        pml.velocity[2] = 80;
                    783:                else
                    784:                        pml.velocity[2] = 50;
                    785:                return;
                    786:        }
1.1.1.2 ! root      787: 
1.1       root      788:        if (pm->groundentity == NULL)
                    789:                return;         // in air, so no effect
1.1.1.2 ! root      790: 
1.1       root      791:        pm->s.pm_flags |= PMF_JUMP_HELD;
                    792: 
                    793:        pm->groundentity = NULL;
1.1.1.2 ! root      794:        pml.velocity[2] += 270;
        !           795:        if (pml.velocity[2] < 270)
        !           796:                pml.velocity[2] = 270;
1.1       root      797: }
1.1.1.2 ! root      798: 
        !           799: 
1.1       root      800: /*
                    801: =============
                    802: PM_CheckSpecialMovement
                    803: =============
                    804: */
                    805: void PM_CheckSpecialMovement (void)
                    806: {
                    807:        vec3_t  spot;
                    808:        int             cont;
                    809:        vec3_t  flatforward;
                    810:        trace_t trace;
                    811: 
                    812:        if (pm->s.pm_time)
                    813:                return;
                    814: 
                    815:        pml.ladder = false;
1.1.1.2 ! root      816: 
1.1       root      817:        // check for ladder
                    818:        flatforward[0] = pml.forward[0];
                    819:        flatforward[1] = pml.forward[1];
                    820:        flatforward[2] = 0;
                    821:        VectorNormalize (flatforward);
1.1.1.2 ! root      822: 
1.1       root      823:        VectorMA (pml.origin, 1, flatforward, spot);
                    824:        trace = pm->trace (pml.origin, pm->mins, pm->maxs, spot);
                    825:        if ((trace.fraction < 1) && (trace.contents & CONTENTS_LADDER))
                    826:                pml.ladder = true;
1.1.1.2 ! root      827: 
1.1       root      828:        // check for water jump
                    829:        if (pm->waterlevel != 2)
                    830:                return;
1.1.1.2 ! root      831: 
1.1       root      832:        VectorMA (pml.origin, 30, flatforward, spot);
                    833:        spot[2] += 4;
                    834:        cont = pm->pointcontents (spot);
                    835:        if (!(cont & CONTENTS_SOLID))
                    836:                return;
1.1.1.2 ! root      837: 
1.1       root      838:        spot[2] += 16;
                    839:        cont = pm->pointcontents (spot);
                    840:        if (cont)
                    841:                return;
                    842:        // jump out of water
1.1.1.2 ! root      843:        VectorScale (flatforward, 50, pml.velocity);
1.1       root      844:        pml.velocity[2] = 350;
                    845: 
                    846:        pm->s.pm_flags |= PMF_TIME_WATERJUMP;
                    847:        pm->s.pm_time = 255;
                    848: }
1.1.1.2 ! root      849: 
        !           850: 
1.1       root      851: /*
                    852: ===============
1.1.1.2 ! root      853: PM_FlyMove
1.1       root      854: ===============
                    855: */
1.1.1.2 ! root      856: void PM_FlyMove (qboolean doclip)
1.1       root      857: {
                    858:        float   speed, drop, friction, control, newspeed;
                    859:        float   currentspeed, addspeed, accelspeed;
                    860:        int                     i;
                    861:        vec3_t          wishvel;
                    862:        float           fmove, smove;
                    863:        vec3_t          wishdir;
                    864:        float           wishspeed;
1.1.1.2 ! root      865:        vec3_t          end;
        !           866:        trace_t trace;
1.1       root      867: 
                    868:        pm->viewheight = 22;
1.1.1.2 ! root      869: 
1.1       root      870:        // friction
1.1.1.2 ! root      871: 
1.1       root      872:        speed = VectorLength (pml.velocity);
                    873:        if (speed < 1)
                    874:        {
                    875:                VectorCopy (vec3_origin, pml.velocity);
                    876:        }
                    877:        else
                    878:        {
                    879:                drop = 0;
1.1.1.2 ! root      880: 
1.1       root      881:                friction = pm_friction*1.5;     // extra friction
                    882:                control = speed < pm_stopspeed ? pm_stopspeed : speed;
                    883:                drop += control*friction*pml.frametime;
1.1.1.2 ! root      884: 
1.1       root      885:                // scale the velocity
                    886:                newspeed = speed - drop;
                    887:                if (newspeed < 0)
                    888:                        newspeed = 0;
                    889:                newspeed /= speed;
1.1.1.2 ! root      890: 
1.1       root      891:                VectorScale (pml.velocity, newspeed, pml.velocity);
                    892:        }
1.1.1.2 ! root      893: 
1.1       root      894:        // accelerate
                    895:        fmove = pm->cmd.forwardmove;
                    896:        smove = pm->cmd.sidemove;
                    897:        
                    898:        VectorNormalize (pml.forward);
                    899:        VectorNormalize (pml.right);
1.1.1.2 ! root      900: 
1.1       root      901:        for (i=0 ; i<3 ; i++)
                    902:                wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
                    903:        wishvel[2] += pm->cmd.upmove;
1.1.1.2 ! root      904: 
1.1       root      905:        VectorCopy (wishvel, wishdir);
                    906:        wishspeed = VectorNormalize(wishdir);
1.1.1.2 ! root      907: 
1.1       root      908:        //
                    909:        // clamp to server defined max speed
                    910:        //
                    911:        if (wishspeed > pm_maxspeed)
                    912:        {
                    913:                VectorScale (wishvel, pm_maxspeed/wishspeed, wishvel);
                    914:                wishspeed = pm_maxspeed;
                    915:        }
1.1.1.2 ! root      916: 
        !           917: 
1.1       root      918:        currentspeed = DotProduct(pml.velocity, wishdir);
                    919:        addspeed = wishspeed - currentspeed;
                    920:        if (addspeed <= 0)
                    921:                return;
                    922:        accelspeed = pm_accelerate*pml.frametime*wishspeed;
                    923:        if (accelspeed > addspeed)
                    924:                accelspeed = addspeed;
                    925:        
                    926:        for (i=0 ; i<3 ; i++)
                    927:                pml.velocity[i] += accelspeed*wishdir[i];       
1.1.1.2 ! root      928: 
        !           929:        if (doclip) {
        !           930:                for (i=0 ; i<3 ; i++)
        !           931:                        end[i] = pml.origin[i] + pml.frametime * pml.velocity[i];
        !           932: 
        !           933:                trace = pm->trace (pml.origin, pm->mins, pm->maxs, end);
        !           934: 
        !           935:                VectorCopy (trace.endpos, pml.origin);
        !           936:        } else {
        !           937:                // move
        !           938:                VectorMA (pml.origin, pml.frametime, pml.velocity, pml.origin);
        !           939:        }
1.1       root      940: }
1.1.1.2 ! root      941: 
        !           942: 
1.1       root      943: /*
                    944: ==============
                    945: PM_CheckDuck
                    946: 
                    947: Sets mins, maxs, and pm->viewheight
                    948: ==============
                    949: */
                    950: void PM_CheckDuck (void)
                    951: {
                    952:        trace_t trace;
                    953: 
                    954:        pm->mins[0] = -16;
                    955:        pm->mins[1] = -16;
                    956: 
                    957:        pm->maxs[0] = 16;
                    958:        pm->maxs[1] = 16;
1.1.1.2 ! root      959: 
1.1       root      960:        if (pm->s.pm_type == PM_GIB)
                    961:        {
                    962:                pm->mins[2] = 0;
                    963:                pm->maxs[2] = 16;
                    964:                pm->viewheight = 8;
                    965:                return;
                    966:        }
                    967: 
                    968:        pm->mins[2] = -24;
                    969: 
                    970:        if (pm->s.pm_type == PM_DEAD)
                    971:        {
                    972:                pm->s.pm_flags |= PMF_DUCKED;
                    973:        }
                    974:        else if (pm->cmd.upmove < 0 && (pm->s.pm_flags & PMF_ON_GROUND) )
                    975:        {       // duck
                    976:                pm->s.pm_flags |= PMF_DUCKED;
                    977:        }
                    978:        else
                    979:        {       // stand up if possible
                    980:                if (pm->s.pm_flags & PMF_DUCKED)
                    981:                {
                    982:                        // try to stand up
                    983:                        pm->maxs[2] = 32;
                    984:                        trace = pm->trace (pml.origin, pm->mins, pm->maxs, pml.origin);
                    985:                        if (!trace.allsolid)
                    986:                                pm->s.pm_flags &= ~PMF_DUCKED;
                    987:                }
                    988:        }
                    989: 
                    990:        if (pm->s.pm_flags & PMF_DUCKED)
                    991:        {
                    992:                pm->maxs[2] = 4;
                    993:                pm->viewheight = -2;
                    994:        }
                    995:        else
                    996:        {
                    997:                pm->maxs[2] = 32;
                    998:                pm->viewheight = 22;
                    999:        }
                   1000: }
                   1001: 
1.1.1.2 ! root     1002: 
1.1       root     1003: /*
                   1004: ==============
                   1005: PM_DeadMove
                   1006: ==============
                   1007: */
                   1008: void PM_DeadMove (void)
                   1009: {
                   1010:        float   forward;
                   1011: 
                   1012:        if (!pm->groundentity)
                   1013:                return;
                   1014: 
                   1015:        // extra friction
                   1016: 
                   1017:        forward = VectorLength (pml.velocity);
                   1018:        forward -= 20;
                   1019:        if (forward <= 0)
                   1020:        {
                   1021:                VectorClear (pml.velocity);
                   1022:        }
                   1023:        else
                   1024:        {
                   1025:                VectorNormalize (pml.velocity);
                   1026:                VectorScale (pml.velocity, forward, pml.velocity);
                   1027:        }
                   1028: }
                   1029: 
                   1030: 
                   1031: qboolean       PM_GoodPosition (void)
                   1032: {
                   1033:        trace_t trace;
                   1034:        vec3_t  origin, end;
                   1035:        int             i;
                   1036: 
                   1037:        if (pm->s.pm_type == PM_SPECTATOR)
                   1038:                return true;
                   1039: 
                   1040:        for (i=0 ; i<3 ; i++)
                   1041:                origin[i] = end[i] = pm->s.origin[i]*0.125;
                   1042:        trace = pm->trace (origin, pm->mins, pm->maxs, end);
                   1043: 
                   1044:        return !trace.allsolid;
                   1045: }
                   1046: 
                   1047: /*
                   1048: ================
                   1049: PM_SnapPosition
                   1050: 
                   1051: On exit, the origin will have a value that is pre-quantized to the 0.125
                   1052: precision of the network channel and in a valid position.
                   1053: ================
                   1054: */
                   1055: void PM_SnapPosition (void)
                   1056: {
                   1057:        int             sign[3];
                   1058:        int             i, j, bits;
                   1059:        short   base[3];
                   1060:        // try all single bits first
                   1061:        static int jitterbits[8] = {0,4,1,2,3,5,6,7};
                   1062: 
                   1063:        // snap velocity to eigths
                   1064:        for (i=0 ; i<3 ; i++)
                   1065:                pm->s.velocity[i] = (int)(pml.velocity[i]*8);
                   1066: 
                   1067:        for (i=0 ; i<3 ; i++)
                   1068:        {
                   1069:                if (pml.origin[i] >= 0)
                   1070:                        sign[i] = 1;
                   1071:                else 
                   1072:                        sign[i] = -1;
                   1073:                pm->s.origin[i] = (int)(pml.origin[i]*8);
                   1074:                if (pm->s.origin[i]*0.125 == pml.origin[i])
                   1075:                        sign[i] = 0;
                   1076:        }
                   1077:        VectorCopy (pm->s.origin, base);
                   1078: 
                   1079:        // try all combinations
                   1080:        for (j=0 ; j<8 ; j++)
                   1081:        {
                   1082:                bits = jitterbits[j];
                   1083:                VectorCopy (base, pm->s.origin);
                   1084:                for (i=0 ; i<3 ; i++)
                   1085:                        if (bits & (1<<i) )
                   1086:                                pm->s.origin[i] += sign[i];
                   1087: 
                   1088:                if (PM_GoodPosition ())
                   1089:                        return;
                   1090:        }
                   1091: 
                   1092:        // go back to the last position
                   1093:        VectorCopy (pml.previous_origin, pm->s.origin);
                   1094: //     Com_DPrintf ("using previous_origin\n");
                   1095: }
                   1096: 
1.1.1.2 ! root     1097: #if 0
        !          1098: //NO LONGER USED
1.1       root     1099: /*
                   1100: ================
                   1101: PM_InitialSnapPosition
                   1102: 
                   1103: ================
                   1104: */
                   1105: void PM_InitialSnapPosition (void)
                   1106: {
                   1107:        int             x, y, z;
                   1108:        short   base[3];
                   1109: 
                   1110:        VectorCopy (pm->s.origin, base);
                   1111: 
                   1112:        for (z=1 ; z>=-1 ; z--)
                   1113:        {
                   1114:                pm->s.origin[2] = base[2] + z;
                   1115:                for (y=1 ; y>=-1 ; y--)
                   1116:                {
                   1117:                        pm->s.origin[1] = base[1] + y;
                   1118:                        for (x=1 ; x>=-1 ; x--)
                   1119:                        {
                   1120:                                pm->s.origin[0] = base[0] + x;
                   1121:                                if (PM_GoodPosition ())
                   1122:                                {
                   1123:                                        pml.origin[0] = pm->s.origin[0]*0.125;
                   1124:                                        pml.origin[1] = pm->s.origin[1]*0.125;
                   1125:                                        pml.origin[2] = pm->s.origin[2]*0.125;
                   1126:                                        VectorCopy (pm->s.origin, pml.previous_origin);
                   1127:                                        return;
                   1128:                                }
                   1129:                        }
                   1130:                }
                   1131:        }
                   1132: 
                   1133:        Com_DPrintf ("Bad InitialSnapPosition\n");
                   1134: }
1.1.1.2 ! root     1135: #else
        !          1136: /*
        !          1137: ================
        !          1138: PM_InitialSnapPosition
        !          1139: 
        !          1140: ================
        !          1141: */
        !          1142: void PM_InitialSnapPosition(void)
        !          1143: {
        !          1144:        int        x, y, z;
        !          1145:        short      base[3];
        !          1146:        static int offset[3] = { 0, -1, 1 };
        !          1147: 
        !          1148:        VectorCopy (pm->s.origin, base);
        !          1149: 
        !          1150:        for ( z = 0; z < 3; z++ ) {
        !          1151:                pm->s.origin[2] = base[2] + offset[ z ];
        !          1152:                for ( y = 0; y < 3; y++ ) {
        !          1153:                        pm->s.origin[1] = base[1] + offset[ y ];
        !          1154:                        for ( x = 0; x < 3; x++ ) {
        !          1155:                                pm->s.origin[0] = base[0] + offset[ x ];
        !          1156:                                if (PM_GoodPosition ()) {
        !          1157:                                        pml.origin[0] = pm->s.origin[0]*0.125;
        !          1158:                                        pml.origin[1] = pm->s.origin[1]*0.125;
        !          1159:                                        pml.origin[2] = pm->s.origin[2]*0.125;
        !          1160:                                        VectorCopy (pm->s.origin, pml.previous_origin);
        !          1161:                                        return;
        !          1162:                                }
        !          1163:                        }
        !          1164:                }
        !          1165:        }
        !          1166: 
        !          1167:        Com_DPrintf ("Bad InitialSnapPosition\n");
        !          1168: }
        !          1169: 
        !          1170: #endif
1.1       root     1171: 
                   1172: /*
                   1173: ================
                   1174: PM_ClampAngles
                   1175: 
                   1176: ================
                   1177: */
                   1178: void PM_ClampAngles (void)
                   1179: {
                   1180:        short   temp;
                   1181:        int             i;
                   1182: 
                   1183:        if (pm->s.pm_flags & PMF_TIME_TELEPORT)
                   1184:        {
                   1185:                pm->viewangles[YAW] = SHORT2ANGLE(pm->cmd.angles[YAW] + pm->s.delta_angles[YAW]);
                   1186:                pm->viewangles[PITCH] = 0;
                   1187:                pm->viewangles[ROLL] = 0;
                   1188:        }
                   1189:        else
                   1190:        {
                   1191:                // circularly clamp the angles with deltas
                   1192:                for (i=0 ; i<3 ; i++)
                   1193:                {
                   1194:                        temp = pm->cmd.angles[i] + pm->s.delta_angles[i];
                   1195:                        pm->viewangles[i] = SHORT2ANGLE(temp);
                   1196:                }
                   1197: 
                   1198:                // don't let the player look up or down more than 90 degrees
                   1199:                if (pm->viewangles[PITCH] > 89 && pm->viewangles[PITCH] < 180)
                   1200:                        pm->viewangles[PITCH] = 89;
                   1201:                else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
                   1202:                        pm->viewangles[PITCH] = 271;
                   1203:        }
                   1204:        AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up);
                   1205: }
                   1206: 
                   1207: /*
                   1208: ================
                   1209: Pmove
                   1210: 
                   1211: Can be called by either the server or the client
                   1212: ================
                   1213: */
                   1214: void Pmove (pmove_t *pmove)
                   1215: {
                   1216:        pm = pmove;
                   1217: 
                   1218:        // clear results
                   1219:        pm->numtouch = 0;
                   1220:        VectorClear (pm->viewangles);
                   1221:        pm->viewheight = 0;
                   1222:        pm->groundentity = 0;
                   1223:        pm->watertype = 0;
                   1224:        pm->waterlevel = 0;
                   1225: 
                   1226:        // clear all pmove local vars
                   1227:        memset (&pml, 0, sizeof(pml));
                   1228: 
                   1229:        // convert origin and velocity to float values
                   1230:        pml.origin[0] = pm->s.origin[0]*0.125;
                   1231:        pml.origin[1] = pm->s.origin[1]*0.125;
                   1232:        pml.origin[2] = pm->s.origin[2]*0.125;
                   1233: 
                   1234:        pml.velocity[0] = pm->s.velocity[0]*0.125;
                   1235:        pml.velocity[1] = pm->s.velocity[1]*0.125;
                   1236:        pml.velocity[2] = pm->s.velocity[2]*0.125;
                   1237: 
                   1238:        // save old org in case we get stuck
                   1239:        VectorCopy (pm->s.origin, pml.previous_origin);
                   1240: 
                   1241:        pml.frametime = pm->cmd.msec * 0.001;
                   1242: 
                   1243:        PM_ClampAngles ();
                   1244: 
                   1245:        if (pm->s.pm_type == PM_SPECTATOR)
                   1246:        {
1.1.1.2 ! root     1247:                PM_FlyMove (false);
1.1       root     1248:                PM_SnapPosition ();
                   1249:                return;
                   1250:        }
                   1251: 
                   1252:        if (pm->s.pm_type >= PM_DEAD)
                   1253:        {
                   1254:                pm->cmd.forwardmove = 0;
                   1255:                pm->cmd.sidemove = 0;
                   1256:                pm->cmd.upmove = 0;
                   1257:        }
                   1258: 
                   1259:        if (pm->s.pm_type == PM_FREEZE)
                   1260:                return;         // no movement at all
                   1261: 
                   1262:        // set mins, maxs, and viewheight
                   1263:        PM_CheckDuck ();
                   1264: 
                   1265:        if (pm->snapinitial)
                   1266:                PM_InitialSnapPosition ();
                   1267: 
                   1268:        // set groundentity, watertype, and waterlevel
                   1269:        PM_CatagorizePosition ();
                   1270: 
                   1271:        if (pm->s.pm_type == PM_DEAD)
                   1272:                PM_DeadMove ();
                   1273: 
                   1274:        PM_CheckSpecialMovement ();
                   1275: 
                   1276:        // drop timing counter
                   1277:        if (pm->s.pm_time)
                   1278:        {
                   1279:                int             msec;
                   1280: 
                   1281:                msec = pm->cmd.msec >> 3;
                   1282:                if (!msec)
                   1283:                        msec = 1;
                   1284:                if ( msec >= pm->s.pm_time) 
                   1285:                {
                   1286:                        pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                   1287:                        pm->s.pm_time = 0;
                   1288:                }
                   1289:                else
                   1290:                        pm->s.pm_time -= msec;
                   1291:        }
                   1292: 
                   1293:        if (pm->s.pm_flags & PMF_TIME_TELEPORT)
                   1294:        {       // teleport pause stays exactly in place
                   1295:        }
                   1296:        else if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
                   1297:        {       // waterjump has no control, but falls
                   1298:                pml.velocity[2] -= pm->s.gravity * pml.frametime;
                   1299:                if (pml.velocity[2] < 0)
                   1300:                {       // cancel as soon as we are falling down again
                   1301:                        pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                   1302:                        pm->s.pm_time = 0;
                   1303:                }
                   1304: 
                   1305:                PM_StepSlideMove ();
                   1306:        }
                   1307:        else
                   1308:        {
                   1309:                PM_CheckJump ();
                   1310: 
                   1311:                PM_Friction ();
                   1312: 
                   1313:                if (pm->waterlevel >= 2)
                   1314:                        PM_WaterMove ();
1.1.1.2 ! root     1315:                else {
        !          1316:                        vec3_t  angles;
        !          1317: 
        !          1318:                        VectorCopy(pm->viewangles, angles);
        !          1319:                        if (angles[PITCH] > 180)
        !          1320:                                angles[PITCH] = angles[PITCH] - 360;
        !          1321:                        angles[PITCH] /= 3;
        !          1322: 
        !          1323:                        AngleVectors (angles, pml.forward, pml.right, pml.up);
        !          1324: 
1.1       root     1325:                        PM_AirMove ();
1.1.1.2 ! root     1326:                }
1.1       root     1327:        }
                   1328: 
                   1329:        // set groundentity, watertype, and waterlevel for final spot
                   1330:        PM_CatagorizePosition ();
                   1331: 
                   1332:        PM_SnapPosition ();
                   1333: }
1.1.1.2 ! root     1334: 

unix.superglobalmegacorp.com

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