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

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

unix.superglobalmegacorp.com

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