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

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;
1.1.1.3 ! root       38: float  pm_airaccelerate = 0;
1.1       root       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.3 ! root      354:        if (pm->waterlevel && !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.3 ! root      620: 
        !           621: // PGM -- fix for negative trigger_gravity fields
        !           622: //             pml.velocity[2] = 0;
        !           623:                if(pm->s.gravity > 0)
        !           624:                        pml.velocity[2] = 0;
        !           625:                else
        !           626:                        pml.velocity[2] -= pm->s.gravity * pml.frametime;
        !           627: // PGM
        !           628: 
1.1       root      629:                if (!pml.velocity[0] && !pml.velocity[1])
                    630:                        return;
                    631:                PM_StepSlideMove ();
                    632:        }
                    633:        else
                    634:        {       // not on ground, so little effect on velocity
1.1.1.3 ! root      635:                if (pm_airaccelerate)
        !           636:                        PM_AirAccelerate (wishdir, wishspeed, pm_accelerate);
        !           637:                else
        !           638:                        PM_Accelerate (wishdir, wishspeed, 1);
1.1       root      639:                // add gravity
                    640:                pml.velocity[2] -= pm->s.gravity * pml.frametime;
                    641:                PM_StepSlideMove ();
                    642:        }
                    643: }
1.1.1.2   root      644: 
                    645: 
                    646: 
1.1       root      647: /*
                    648: =============
                    649: PM_CatagorizePosition
                    650: =============
                    651: */
                    652: void PM_CatagorizePosition (void)
                    653: {
                    654:        vec3_t          point;
                    655:        int                     cont;
                    656:        trace_t         trace;
                    657:        int                     sample1;
                    658:        int                     sample2;
1.1.1.2   root      659: 
1.1       root      660: // if the player hull point one unit down is solid, the player
                    661: // is on ground
1.1.1.2   root      662: 
1.1       root      663: // see if standing on something solid  
                    664:        point[0] = pml.origin[0];
                    665:        point[1] = pml.origin[1];
                    666:        point[2] = pml.origin[2] - 0.25;
1.1.1.2   root      667:        if (pml.velocity[2] > 180) //!!ZOID changed from 100 to 180 (ramp accel)
1.1       root      668:        {
                    669:                pm->s.pm_flags &= ~PMF_ON_GROUND;
                    670:                pm->groundentity = NULL;
                    671:        }
                    672:        else
                    673:        {
                    674:                trace = pm->trace (pml.origin, pm->mins, pm->maxs, point);
                    675:                pml.groundplane = trace.plane;
                    676:                pml.groundsurface = trace.surface;
                    677:                pml.groundcontents = trace.contents;
                    678: 
                    679:                if (!trace.ent || (trace.plane.normal[2] < 0.7 && !trace.startsolid) )
                    680:                {
                    681:                        pm->groundentity = NULL;
                    682:                        pm->s.pm_flags &= ~PMF_ON_GROUND;
                    683:                }
                    684:                else
                    685:                {
                    686:                        pm->groundentity = trace.ent;
                    687: 
                    688:                        // hitting solid ground will end a waterjump
                    689:                        if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
                    690:                        {
                    691:                                pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                    692:                                pm->s.pm_time = 0;
                    693:                        }
                    694: 
                    695:                        if (! (pm->s.pm_flags & PMF_ON_GROUND) )
                    696:                        {       // just hit the ground
                    697:                                pm->s.pm_flags |= PMF_ON_GROUND;
                    698:                                // don't do landing time if we were just going down a slope
                    699:                                if (pml.velocity[2] < -200)
                    700:                                {
                    701:                                        pm->s.pm_flags |= PMF_TIME_LAND;
                    702:                                        // don't allow another jump for a little while
                    703:                                        if (pml.velocity[2] < -400)
                    704:                                                pm->s.pm_time = 25;     
                    705:                                        else
                    706:                                                pm->s.pm_time = 18;
                    707:                                }
                    708:                        }
                    709:                }
1.1.1.2   root      710: 
                    711: #if 0
1.1       root      712:                if (trace.fraction < 1.0 && trace.ent && pml.velocity[2] < 0)
                    713:                        pml.velocity[2] = 0;
1.1.1.2   root      714: #endif
1.1       root      715: 
                    716:                if (pm->numtouch < MAXTOUCH && trace.ent)
                    717:                {
                    718:                        pm->touchents[pm->numtouch] = trace.ent;
                    719:                        pm->numtouch++;
                    720:                }
                    721:        }
1.1.1.2   root      722: 
1.1       root      723: //
                    724: // get waterlevel, accounting for ducking
                    725: //
                    726:        pm->waterlevel = 0;
                    727:        pm->watertype = 0;
1.1.1.2   root      728: 
1.1       root      729:        sample2 = pm->viewheight - pm->mins[2];
                    730:        sample1 = sample2 / 2;
1.1.1.2   root      731: 
1.1       root      732:        point[2] = pml.origin[2] + pm->mins[2] + 1;     
                    733:        cont = pm->pointcontents (point);
1.1.1.2   root      734: 
1.1       root      735:        if (cont & MASK_WATER)
                    736:        {
                    737:                pm->watertype = cont;
                    738:                pm->waterlevel = 1;
                    739:                point[2] = pml.origin[2] + pm->mins[2] + sample1;
                    740:                cont = pm->pointcontents (point);
                    741:                if (cont & MASK_WATER)
                    742:                {
                    743:                        pm->waterlevel = 2;
                    744:                        point[2] = pml.origin[2] + pm->mins[2] + sample2;
                    745:                        cont = pm->pointcontents (point);
                    746:                        if (cont & MASK_WATER)
                    747:                                pm->waterlevel = 3;
                    748:                }
                    749:        }
1.1.1.2   root      750: 
1.1       root      751: }
1.1.1.2   root      752: 
                    753: 
1.1       root      754: /*
                    755: =============
                    756: PM_CheckJump
                    757: =============
                    758: */
                    759: void PM_CheckJump (void)
                    760: {
                    761:        if (pm->s.pm_flags & PMF_TIME_LAND)
                    762:        {       // hasn't been long enough since landing to jump again
                    763:                return;
                    764:        }
1.1.1.2   root      765: 
1.1       root      766:        if (pm->cmd.upmove < 10)
                    767:        {       // not holding jump
                    768:                pm->s.pm_flags &= ~PMF_JUMP_HELD;
                    769:                return;
                    770:        }
                    771: 
                    772:        // must wait for jump to be released
                    773:        if (pm->s.pm_flags & PMF_JUMP_HELD)
                    774:                return;
                    775: 
                    776:        if (pm->s.pm_type == PM_DEAD)
                    777:                return;
1.1.1.2   root      778: 
1.1       root      779:        if (pm->waterlevel >= 2)
                    780:        {       // swimming, not jumping
                    781:                pm->groundentity = NULL;
1.1.1.2   root      782: 
1.1       root      783:                if (pml.velocity[2] <= -300)
                    784:                        return;
                    785: 
                    786:                if (pm->watertype == CONTENTS_WATER)
                    787:                        pml.velocity[2] = 100;
                    788:                else if (pm->watertype == CONTENTS_SLIME)
                    789:                        pml.velocity[2] = 80;
                    790:                else
                    791:                        pml.velocity[2] = 50;
                    792:                return;
                    793:        }
1.1.1.2   root      794: 
1.1       root      795:        if (pm->groundentity == NULL)
                    796:                return;         // in air, so no effect
1.1.1.2   root      797: 
1.1       root      798:        pm->s.pm_flags |= PMF_JUMP_HELD;
                    799: 
                    800:        pm->groundentity = NULL;
1.1.1.2   root      801:        pml.velocity[2] += 270;
                    802:        if (pml.velocity[2] < 270)
                    803:                pml.velocity[2] = 270;
1.1       root      804: }
1.1.1.2   root      805: 
                    806: 
1.1       root      807: /*
                    808: =============
                    809: PM_CheckSpecialMovement
                    810: =============
                    811: */
                    812: void PM_CheckSpecialMovement (void)
                    813: {
                    814:        vec3_t  spot;
                    815:        int             cont;
                    816:        vec3_t  flatforward;
                    817:        trace_t trace;
                    818: 
                    819:        if (pm->s.pm_time)
                    820:                return;
                    821: 
                    822:        pml.ladder = false;
1.1.1.2   root      823: 
1.1       root      824:        // check for ladder
                    825:        flatforward[0] = pml.forward[0];
                    826:        flatforward[1] = pml.forward[1];
                    827:        flatforward[2] = 0;
                    828:        VectorNormalize (flatforward);
1.1.1.2   root      829: 
1.1       root      830:        VectorMA (pml.origin, 1, flatforward, spot);
                    831:        trace = pm->trace (pml.origin, pm->mins, pm->maxs, spot);
                    832:        if ((trace.fraction < 1) && (trace.contents & CONTENTS_LADDER))
                    833:                pml.ladder = true;
1.1.1.2   root      834: 
1.1       root      835:        // check for water jump
                    836:        if (pm->waterlevel != 2)
                    837:                return;
1.1.1.2   root      838: 
1.1       root      839:        VectorMA (pml.origin, 30, flatforward, spot);
                    840:        spot[2] += 4;
                    841:        cont = pm->pointcontents (spot);
                    842:        if (!(cont & CONTENTS_SOLID))
                    843:                return;
1.1.1.2   root      844: 
1.1       root      845:        spot[2] += 16;
                    846:        cont = pm->pointcontents (spot);
                    847:        if (cont)
                    848:                return;
                    849:        // jump out of water
1.1.1.2   root      850:        VectorScale (flatforward, 50, pml.velocity);
1.1       root      851:        pml.velocity[2] = 350;
                    852: 
                    853:        pm->s.pm_flags |= PMF_TIME_WATERJUMP;
                    854:        pm->s.pm_time = 255;
                    855: }
1.1.1.2   root      856: 
                    857: 
1.1       root      858: /*
                    859: ===============
1.1.1.2   root      860: PM_FlyMove
1.1       root      861: ===============
                    862: */
1.1.1.2   root      863: void PM_FlyMove (qboolean doclip)
1.1       root      864: {
                    865:        float   speed, drop, friction, control, newspeed;
                    866:        float   currentspeed, addspeed, accelspeed;
                    867:        int                     i;
                    868:        vec3_t          wishvel;
                    869:        float           fmove, smove;
                    870:        vec3_t          wishdir;
                    871:        float           wishspeed;
1.1.1.2   root      872:        vec3_t          end;
                    873:        trace_t trace;
1.1       root      874: 
                    875:        pm->viewheight = 22;
1.1.1.2   root      876: 
1.1       root      877:        // friction
1.1.1.2   root      878: 
1.1       root      879:        speed = VectorLength (pml.velocity);
                    880:        if (speed < 1)
                    881:        {
                    882:                VectorCopy (vec3_origin, pml.velocity);
                    883:        }
                    884:        else
                    885:        {
                    886:                drop = 0;
1.1.1.2   root      887: 
1.1       root      888:                friction = pm_friction*1.5;     // extra friction
                    889:                control = speed < pm_stopspeed ? pm_stopspeed : speed;
                    890:                drop += control*friction*pml.frametime;
1.1.1.2   root      891: 
1.1       root      892:                // scale the velocity
                    893:                newspeed = speed - drop;
                    894:                if (newspeed < 0)
                    895:                        newspeed = 0;
                    896:                newspeed /= speed;
1.1.1.2   root      897: 
1.1       root      898:                VectorScale (pml.velocity, newspeed, pml.velocity);
                    899:        }
1.1.1.2   root      900: 
1.1       root      901:        // accelerate
                    902:        fmove = pm->cmd.forwardmove;
                    903:        smove = pm->cmd.sidemove;
                    904:        
                    905:        VectorNormalize (pml.forward);
                    906:        VectorNormalize (pml.right);
1.1.1.2   root      907: 
1.1       root      908:        for (i=0 ; i<3 ; i++)
                    909:                wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
                    910:        wishvel[2] += pm->cmd.upmove;
1.1.1.2   root      911: 
1.1       root      912:        VectorCopy (wishvel, wishdir);
                    913:        wishspeed = VectorNormalize(wishdir);
1.1.1.2   root      914: 
1.1       root      915:        //
                    916:        // clamp to server defined max speed
                    917:        //
                    918:        if (wishspeed > pm_maxspeed)
                    919:        {
                    920:                VectorScale (wishvel, pm_maxspeed/wishspeed, wishvel);
                    921:                wishspeed = pm_maxspeed;
                    922:        }
1.1.1.2   root      923: 
                    924: 
1.1       root      925:        currentspeed = DotProduct(pml.velocity, wishdir);
                    926:        addspeed = wishspeed - currentspeed;
                    927:        if (addspeed <= 0)
                    928:                return;
                    929:        accelspeed = pm_accelerate*pml.frametime*wishspeed;
                    930:        if (accelspeed > addspeed)
                    931:                accelspeed = addspeed;
                    932:        
                    933:        for (i=0 ; i<3 ; i++)
                    934:                pml.velocity[i] += accelspeed*wishdir[i];       
1.1.1.2   root      935: 
                    936:        if (doclip) {
                    937:                for (i=0 ; i<3 ; i++)
                    938:                        end[i] = pml.origin[i] + pml.frametime * pml.velocity[i];
                    939: 
                    940:                trace = pm->trace (pml.origin, pm->mins, pm->maxs, end);
                    941: 
                    942:                VectorCopy (trace.endpos, pml.origin);
                    943:        } else {
                    944:                // move
                    945:                VectorMA (pml.origin, pml.frametime, pml.velocity, pml.origin);
                    946:        }
1.1       root      947: }
1.1.1.2   root      948: 
                    949: 
1.1       root      950: /*
                    951: ==============
                    952: PM_CheckDuck
                    953: 
                    954: Sets mins, maxs, and pm->viewheight
                    955: ==============
                    956: */
                    957: void PM_CheckDuck (void)
                    958: {
                    959:        trace_t trace;
                    960: 
                    961:        pm->mins[0] = -16;
                    962:        pm->mins[1] = -16;
                    963: 
                    964:        pm->maxs[0] = 16;
                    965:        pm->maxs[1] = 16;
1.1.1.2   root      966: 
1.1       root      967:        if (pm->s.pm_type == PM_GIB)
                    968:        {
                    969:                pm->mins[2] = 0;
                    970:                pm->maxs[2] = 16;
                    971:                pm->viewheight = 8;
                    972:                return;
                    973:        }
                    974: 
                    975:        pm->mins[2] = -24;
                    976: 
                    977:        if (pm->s.pm_type == PM_DEAD)
                    978:        {
                    979:                pm->s.pm_flags |= PMF_DUCKED;
                    980:        }
                    981:        else if (pm->cmd.upmove < 0 && (pm->s.pm_flags & PMF_ON_GROUND) )
                    982:        {       // duck
                    983:                pm->s.pm_flags |= PMF_DUCKED;
                    984:        }
                    985:        else
                    986:        {       // stand up if possible
                    987:                if (pm->s.pm_flags & PMF_DUCKED)
                    988:                {
                    989:                        // try to stand up
                    990:                        pm->maxs[2] = 32;
                    991:                        trace = pm->trace (pml.origin, pm->mins, pm->maxs, pml.origin);
                    992:                        if (!trace.allsolid)
                    993:                                pm->s.pm_flags &= ~PMF_DUCKED;
                    994:                }
                    995:        }
                    996: 
                    997:        if (pm->s.pm_flags & PMF_DUCKED)
                    998:        {
                    999:                pm->maxs[2] = 4;
                   1000:                pm->viewheight = -2;
                   1001:        }
                   1002:        else
                   1003:        {
                   1004:                pm->maxs[2] = 32;
                   1005:                pm->viewheight = 22;
                   1006:        }
                   1007: }
                   1008: 
1.1.1.2   root     1009: 
1.1       root     1010: /*
                   1011: ==============
                   1012: PM_DeadMove
                   1013: ==============
                   1014: */
                   1015: void PM_DeadMove (void)
                   1016: {
                   1017:        float   forward;
                   1018: 
                   1019:        if (!pm->groundentity)
                   1020:                return;
                   1021: 
                   1022:        // extra friction
                   1023: 
                   1024:        forward = VectorLength (pml.velocity);
                   1025:        forward -= 20;
                   1026:        if (forward <= 0)
                   1027:        {
                   1028:                VectorClear (pml.velocity);
                   1029:        }
                   1030:        else
                   1031:        {
                   1032:                VectorNormalize (pml.velocity);
                   1033:                VectorScale (pml.velocity, forward, pml.velocity);
                   1034:        }
                   1035: }
                   1036: 
                   1037: 
                   1038: qboolean       PM_GoodPosition (void)
                   1039: {
                   1040:        trace_t trace;
                   1041:        vec3_t  origin, end;
                   1042:        int             i;
                   1043: 
                   1044:        if (pm->s.pm_type == PM_SPECTATOR)
                   1045:                return true;
                   1046: 
                   1047:        for (i=0 ; i<3 ; i++)
                   1048:                origin[i] = end[i] = pm->s.origin[i]*0.125;
                   1049:        trace = pm->trace (origin, pm->mins, pm->maxs, end);
                   1050: 
                   1051:        return !trace.allsolid;
                   1052: }
                   1053: 
                   1054: /*
                   1055: ================
                   1056: PM_SnapPosition
                   1057: 
                   1058: On exit, the origin will have a value that is pre-quantized to the 0.125
                   1059: precision of the network channel and in a valid position.
                   1060: ================
                   1061: */
                   1062: void PM_SnapPosition (void)
                   1063: {
                   1064:        int             sign[3];
                   1065:        int             i, j, bits;
                   1066:        short   base[3];
                   1067:        // try all single bits first
                   1068:        static int jitterbits[8] = {0,4,1,2,3,5,6,7};
                   1069: 
                   1070:        // snap velocity to eigths
                   1071:        for (i=0 ; i<3 ; i++)
                   1072:                pm->s.velocity[i] = (int)(pml.velocity[i]*8);
                   1073: 
                   1074:        for (i=0 ; i<3 ; i++)
                   1075:        {
                   1076:                if (pml.origin[i] >= 0)
                   1077:                        sign[i] = 1;
                   1078:                else 
                   1079:                        sign[i] = -1;
                   1080:                pm->s.origin[i] = (int)(pml.origin[i]*8);
                   1081:                if (pm->s.origin[i]*0.125 == pml.origin[i])
                   1082:                        sign[i] = 0;
                   1083:        }
                   1084:        VectorCopy (pm->s.origin, base);
                   1085: 
                   1086:        // try all combinations
                   1087:        for (j=0 ; j<8 ; j++)
                   1088:        {
                   1089:                bits = jitterbits[j];
                   1090:                VectorCopy (base, pm->s.origin);
                   1091:                for (i=0 ; i<3 ; i++)
                   1092:                        if (bits & (1<<i) )
                   1093:                                pm->s.origin[i] += sign[i];
                   1094: 
                   1095:                if (PM_GoodPosition ())
                   1096:                        return;
                   1097:        }
                   1098: 
                   1099:        // go back to the last position
                   1100:        VectorCopy (pml.previous_origin, pm->s.origin);
                   1101: //     Com_DPrintf ("using previous_origin\n");
                   1102: }
                   1103: 
1.1.1.2   root     1104: #if 0
                   1105: //NO LONGER USED
1.1       root     1106: /*
                   1107: ================
                   1108: PM_InitialSnapPosition
                   1109: 
                   1110: ================
                   1111: */
                   1112: void PM_InitialSnapPosition (void)
                   1113: {
                   1114:        int             x, y, z;
                   1115:        short   base[3];
                   1116: 
                   1117:        VectorCopy (pm->s.origin, base);
                   1118: 
                   1119:        for (z=1 ; z>=-1 ; z--)
                   1120:        {
                   1121:                pm->s.origin[2] = base[2] + z;
                   1122:                for (y=1 ; y>=-1 ; y--)
                   1123:                {
                   1124:                        pm->s.origin[1] = base[1] + y;
                   1125:                        for (x=1 ; x>=-1 ; x--)
                   1126:                        {
                   1127:                                pm->s.origin[0] = base[0] + x;
                   1128:                                if (PM_GoodPosition ())
                   1129:                                {
                   1130:                                        pml.origin[0] = pm->s.origin[0]*0.125;
                   1131:                                        pml.origin[1] = pm->s.origin[1]*0.125;
                   1132:                                        pml.origin[2] = pm->s.origin[2]*0.125;
                   1133:                                        VectorCopy (pm->s.origin, pml.previous_origin);
                   1134:                                        return;
                   1135:                                }
                   1136:                        }
                   1137:                }
                   1138:        }
                   1139: 
                   1140:        Com_DPrintf ("Bad InitialSnapPosition\n");
                   1141: }
1.1.1.2   root     1142: #else
                   1143: /*
                   1144: ================
                   1145: PM_InitialSnapPosition
                   1146: 
                   1147: ================
                   1148: */
                   1149: void PM_InitialSnapPosition(void)
                   1150: {
                   1151:        int        x, y, z;
                   1152:        short      base[3];
                   1153:        static int offset[3] = { 0, -1, 1 };
                   1154: 
                   1155:        VectorCopy (pm->s.origin, base);
                   1156: 
                   1157:        for ( z = 0; z < 3; z++ ) {
                   1158:                pm->s.origin[2] = base[2] + offset[ z ];
                   1159:                for ( y = 0; y < 3; y++ ) {
                   1160:                        pm->s.origin[1] = base[1] + offset[ y ];
                   1161:                        for ( x = 0; x < 3; x++ ) {
                   1162:                                pm->s.origin[0] = base[0] + offset[ x ];
                   1163:                                if (PM_GoodPosition ()) {
                   1164:                                        pml.origin[0] = pm->s.origin[0]*0.125;
                   1165:                                        pml.origin[1] = pm->s.origin[1]*0.125;
                   1166:                                        pml.origin[2] = pm->s.origin[2]*0.125;
                   1167:                                        VectorCopy (pm->s.origin, pml.previous_origin);
                   1168:                                        return;
                   1169:                                }
                   1170:                        }
                   1171:                }
                   1172:        }
                   1173: 
                   1174:        Com_DPrintf ("Bad InitialSnapPosition\n");
                   1175: }
                   1176: 
                   1177: #endif
1.1       root     1178: 
                   1179: /*
                   1180: ================
                   1181: PM_ClampAngles
                   1182: 
                   1183: ================
                   1184: */
                   1185: void PM_ClampAngles (void)
                   1186: {
                   1187:        short   temp;
                   1188:        int             i;
                   1189: 
                   1190:        if (pm->s.pm_flags & PMF_TIME_TELEPORT)
                   1191:        {
                   1192:                pm->viewangles[YAW] = SHORT2ANGLE(pm->cmd.angles[YAW] + pm->s.delta_angles[YAW]);
                   1193:                pm->viewangles[PITCH] = 0;
                   1194:                pm->viewangles[ROLL] = 0;
                   1195:        }
                   1196:        else
                   1197:        {
                   1198:                // circularly clamp the angles with deltas
                   1199:                for (i=0 ; i<3 ; i++)
                   1200:                {
                   1201:                        temp = pm->cmd.angles[i] + pm->s.delta_angles[i];
                   1202:                        pm->viewangles[i] = SHORT2ANGLE(temp);
                   1203:                }
                   1204: 
                   1205:                // don't let the player look up or down more than 90 degrees
                   1206:                if (pm->viewangles[PITCH] > 89 && pm->viewangles[PITCH] < 180)
                   1207:                        pm->viewangles[PITCH] = 89;
                   1208:                else if (pm->viewangles[PITCH] < 271 && pm->viewangles[PITCH] >= 180)
                   1209:                        pm->viewangles[PITCH] = 271;
                   1210:        }
                   1211:        AngleVectors (pm->viewangles, pml.forward, pml.right, pml.up);
                   1212: }
                   1213: 
                   1214: /*
                   1215: ================
                   1216: Pmove
                   1217: 
                   1218: Can be called by either the server or the client
                   1219: ================
                   1220: */
                   1221: void Pmove (pmove_t *pmove)
                   1222: {
                   1223:        pm = pmove;
                   1224: 
                   1225:        // clear results
                   1226:        pm->numtouch = 0;
                   1227:        VectorClear (pm->viewangles);
                   1228:        pm->viewheight = 0;
                   1229:        pm->groundentity = 0;
                   1230:        pm->watertype = 0;
                   1231:        pm->waterlevel = 0;
                   1232: 
                   1233:        // clear all pmove local vars
                   1234:        memset (&pml, 0, sizeof(pml));
                   1235: 
                   1236:        // convert origin and velocity to float values
                   1237:        pml.origin[0] = pm->s.origin[0]*0.125;
                   1238:        pml.origin[1] = pm->s.origin[1]*0.125;
                   1239:        pml.origin[2] = pm->s.origin[2]*0.125;
                   1240: 
                   1241:        pml.velocity[0] = pm->s.velocity[0]*0.125;
                   1242:        pml.velocity[1] = pm->s.velocity[1]*0.125;
                   1243:        pml.velocity[2] = pm->s.velocity[2]*0.125;
                   1244: 
                   1245:        // save old org in case we get stuck
                   1246:        VectorCopy (pm->s.origin, pml.previous_origin);
                   1247: 
                   1248:        pml.frametime = pm->cmd.msec * 0.001;
                   1249: 
                   1250:        PM_ClampAngles ();
                   1251: 
                   1252:        if (pm->s.pm_type == PM_SPECTATOR)
                   1253:        {
1.1.1.2   root     1254:                PM_FlyMove (false);
1.1       root     1255:                PM_SnapPosition ();
                   1256:                return;
                   1257:        }
                   1258: 
                   1259:        if (pm->s.pm_type >= PM_DEAD)
                   1260:        {
                   1261:                pm->cmd.forwardmove = 0;
                   1262:                pm->cmd.sidemove = 0;
                   1263:                pm->cmd.upmove = 0;
                   1264:        }
                   1265: 
                   1266:        if (pm->s.pm_type == PM_FREEZE)
                   1267:                return;         // no movement at all
                   1268: 
                   1269:        // set mins, maxs, and viewheight
                   1270:        PM_CheckDuck ();
                   1271: 
                   1272:        if (pm->snapinitial)
                   1273:                PM_InitialSnapPosition ();
                   1274: 
                   1275:        // set groundentity, watertype, and waterlevel
                   1276:        PM_CatagorizePosition ();
                   1277: 
                   1278:        if (pm->s.pm_type == PM_DEAD)
                   1279:                PM_DeadMove ();
                   1280: 
                   1281:        PM_CheckSpecialMovement ();
                   1282: 
                   1283:        // drop timing counter
                   1284:        if (pm->s.pm_time)
                   1285:        {
                   1286:                int             msec;
                   1287: 
                   1288:                msec = pm->cmd.msec >> 3;
                   1289:                if (!msec)
                   1290:                        msec = 1;
                   1291:                if ( msec >= pm->s.pm_time) 
                   1292:                {
                   1293:                        pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                   1294:                        pm->s.pm_time = 0;
                   1295:                }
                   1296:                else
                   1297:                        pm->s.pm_time -= msec;
                   1298:        }
                   1299: 
                   1300:        if (pm->s.pm_flags & PMF_TIME_TELEPORT)
                   1301:        {       // teleport pause stays exactly in place
                   1302:        }
                   1303:        else if (pm->s.pm_flags & PMF_TIME_WATERJUMP)
                   1304:        {       // waterjump has no control, but falls
                   1305:                pml.velocity[2] -= pm->s.gravity * pml.frametime;
                   1306:                if (pml.velocity[2] < 0)
                   1307:                {       // cancel as soon as we are falling down again
                   1308:                        pm->s.pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND | PMF_TIME_TELEPORT);
                   1309:                        pm->s.pm_time = 0;
                   1310:                }
                   1311: 
                   1312:                PM_StepSlideMove ();
                   1313:        }
                   1314:        else
                   1315:        {
                   1316:                PM_CheckJump ();
                   1317: 
                   1318:                PM_Friction ();
                   1319: 
                   1320:                if (pm->waterlevel >= 2)
                   1321:                        PM_WaterMove ();
1.1.1.2   root     1322:                else {
                   1323:                        vec3_t  angles;
                   1324: 
                   1325:                        VectorCopy(pm->viewangles, angles);
                   1326:                        if (angles[PITCH] > 180)
                   1327:                                angles[PITCH] = angles[PITCH] - 360;
                   1328:                        angles[PITCH] /= 3;
                   1329: 
                   1330:                        AngleVectors (angles, pml.forward, pml.right, pml.up);
                   1331: 
1.1       root     1332:                        PM_AirMove ();
1.1.1.2   root     1333:                }
1.1       root     1334:        }
                   1335: 
                   1336:        // set groundentity, watertype, and waterlevel for final spot
                   1337:        PM_CatagorizePosition ();
                   1338: 
                   1339:        PM_SnapPosition ();
                   1340: }
1.1.1.2   root     1341: 

unix.superglobalmegacorp.com

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