Annotation of quakeworld/client/pmove.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: 
                     21: #include "quakedef.h"
                     22: 
                     23: 
                     24: movevars_t             movevars;
                     25: 
                     26: playermove_t   pmove;
                     27: 
                     28: int                    onground;
                     29: int                    waterlevel;
                     30: int                    watertype;
                     31: 
                     32: float          frametime;
                     33: 
                     34: vec3_t         forward, right, up;
                     35: 
                     36: vec3_t player_mins = {-16, -16, -24};
                     37: vec3_t player_maxs = {16, 16, 32};
                     38: 
                     39: // #define     PM_GRAVITY                      800
                     40: // #define     PM_STOPSPEED            100
                     41: // #define     PM_MAXSPEED                     320
                     42: // #define     PM_SPECTATORMAXSPEED    500
                     43: // #define     PM_ACCELERATE           10
                     44: // #define     PM_AIRACCELERATE        0.7
                     45: // #define     PM_WATERACCELERATE      10
                     46: // #define     PM_FRICTION                     6
                     47: // #define     PM_WATERFRICTION        1
                     48: 
                     49: void PM_InitBoxHull (void);
                     50: 
                     51: void Pmove_Init (void)
                     52: {
                     53:        PM_InitBoxHull ();
                     54: }
                     55: 
                     56: #define        STEPSIZE        18
                     57: 
                     58: 
                     59: #define        BUTTON_JUMP     2
                     60: 
                     61: 
                     62: /*
                     63: ==================
                     64: PM_ClipVelocity
                     65: 
                     66: Slide off of the impacting object
                     67: returns the blocked flags (1 = floor, 2 = step / wall)
                     68: ==================
                     69: */
                     70: #define        STOP_EPSILON    0.1
                     71: 
                     72: int PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
                     73: {
                     74:        float   backoff;
                     75:        float   change;
                     76:        int             i, blocked;
                     77:        
                     78:        blocked = 0;
                     79:        if (normal[2] > 0)
                     80:                blocked |= 1;           // floor
                     81:        if (!normal[2])
                     82:                blocked |= 2;           // step
                     83:        
                     84:        backoff = DotProduct (in, normal) * overbounce;
                     85: 
                     86:        for (i=0 ; i<3 ; i++)
                     87:        {
                     88:                change = normal[i]*backoff;
                     89:                out[i] = in[i] - change;
                     90:                if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
                     91:                        out[i] = 0;
                     92:        }
                     93:        
                     94:        return blocked;
                     95: }
                     96: 
                     97: 
                     98: /*
                     99: ============
                    100: PM_FlyMove
                    101: 
                    102: The basic solid body movement clip that slides along multiple planes
                    103: ============
                    104: */
                    105: #define        MAX_CLIP_PLANES 5
                    106: 
                    107: int PM_FlyMove (void)
                    108: {
                    109:        int                     bumpcount, numbumps;
                    110:        vec3_t          dir;
                    111:        float           d;
                    112:        int                     numplanes;
                    113:        vec3_t          planes[MAX_CLIP_PLANES];
                    114:        vec3_t          primal_velocity, original_velocity;
                    115:        int                     i, j;
                    116:        pmtrace_t               trace;
                    117:        vec3_t          end;
                    118:        float           time_left;
                    119:        int                     blocked;
                    120:        
                    121:        numbumps = 4;
                    122:        
                    123:        blocked = 0;
                    124:        VectorCopy (pmove.velocity, original_velocity);
                    125:        VectorCopy (pmove.velocity, primal_velocity);
                    126:        numplanes = 0;
                    127:        
                    128:        time_left = frametime;
                    129: 
                    130:        for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
                    131:        {
                    132:                for (i=0 ; i<3 ; i++)
                    133:                        end[i] = pmove.origin[i] + time_left * pmove.velocity[i];
                    134: 
                    135:                trace = PM_PlayerMove (pmove.origin, end);
                    136: 
                    137:                if (trace.startsolid || trace.allsolid)
                    138:                {       // entity is trapped in another solid
                    139:                        VectorCopy (vec3_origin, pmove.velocity);
                    140:                        return 3;
                    141:                }
                    142: 
                    143:                if (trace.fraction > 0)
                    144:                {       // actually covered some distance
                    145:                        VectorCopy (trace.endpos, pmove.origin);
                    146:                        numplanes = 0;
                    147:                }
                    148: 
                    149:                if (trace.fraction == 1)
                    150:                         break;         // moved the entire distance
                    151: 
                    152:                // save entity for contact
                    153:                pmove.touchindex[pmove.numtouch] = trace.ent;
                    154:                pmove.numtouch++;
                    155: 
                    156:                if (trace.plane.normal[2] > 0.7)
                    157:                {
                    158:                        blocked |= 1;           // floor
                    159:                }
                    160:                if (!trace.plane.normal[2])
                    161:                {
                    162:                        blocked |= 2;           // step
                    163:                }
                    164: 
                    165:                time_left -= time_left * trace.fraction;
                    166:                
                    167:        // cliped to another plane
                    168:                if (numplanes >= MAX_CLIP_PLANES)
                    169:                {       // this shouldn't really happen
                    170:                        VectorCopy (vec3_origin, pmove.velocity);
                    171:                        break;
                    172:                }
                    173: 
                    174:                VectorCopy (trace.plane.normal, planes[numplanes]);
                    175:                numplanes++;
                    176: 
                    177: //
                    178: // modify original_velocity so it parallels all of the clip planes
                    179: //
                    180:                for (i=0 ; i<numplanes ; i++)
                    181:                {
                    182:                        PM_ClipVelocity (original_velocity, planes[i], pmove.velocity, 1);
                    183:                        for (j=0 ; j<numplanes ; j++)
                    184:                                if (j != i)
                    185:                                {
                    186:                                        if (DotProduct (pmove.velocity, planes[j]) < 0)
                    187:                                                break;  // not ok
                    188:                                }
                    189:                        if (j == numplanes)
                    190:                                break;
                    191:                }
                    192:                
                    193:                if (i != numplanes)
                    194:                {       // go along this plane
                    195:                }
                    196:                else
                    197:                {       // go along the crease
                    198:                        if (numplanes != 2)
                    199:                        {
                    200: //                             Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
                    201:                                VectorCopy (vec3_origin, pmove.velocity);
                    202:                                break;
                    203:                        }
                    204:                        CrossProduct (planes[0], planes[1], dir);
                    205:                        d = DotProduct (dir, pmove.velocity);
                    206:                        VectorScale (dir, d, pmove.velocity);
                    207:                }
                    208: 
                    209: //
                    210: // if original velocity is against the original velocity, stop dead
                    211: // to avoid tiny occilations in sloping corners
                    212: //
                    213:                if (DotProduct (pmove.velocity, primal_velocity) <= 0)
                    214:                {
                    215:                        VectorCopy (vec3_origin, pmove.velocity);
                    216:                        break;
                    217:                }
                    218:        }
                    219: 
                    220:        if (pmove.waterjumptime)
                    221:        {
                    222:                VectorCopy (primal_velocity, pmove.velocity);
                    223:        }
                    224:        return blocked;
                    225: }
                    226: 
                    227: /*
                    228: =============
                    229: PM_GroundMove
                    230: 
                    231: Player is on ground, with no upwards velocity
                    232: =============
                    233: */
                    234: void PM_GroundMove (void)
                    235: {
                    236:        vec3_t  start, dest;
                    237:        pmtrace_t       trace;
                    238:        vec3_t  original, originalvel, down, up, downvel;
                    239:        float   downdist, updist;
                    240: 
                    241:        pmove.velocity[2] = 0;
                    242:        if (!pmove.velocity[0] && !pmove.velocity[1] && !pmove.velocity[2])
                    243:                return;
                    244: 
                    245:        // first try just moving to the destination     
                    246:        dest[0] = pmove.origin[0] + pmove.velocity[0]*frametime;
                    247:        dest[1] = pmove.origin[1] + pmove.velocity[1]*frametime;        
                    248:        dest[2] = pmove.origin[2];
                    249: 
                    250:        // first try moving directly to the next spot
                    251:        VectorCopy (dest, start);
                    252:        trace = PM_PlayerMove (pmove.origin, dest);
                    253:        if (trace.fraction == 1)
                    254:        {
                    255:                VectorCopy (trace.endpos, pmove.origin);
                    256:                return;
                    257:        }
                    258: 
                    259:        // try sliding forward both on ground and up 16 pixels
                    260:        // take the move that goes farthest
                    261:        VectorCopy (pmove.origin, original);
                    262:        VectorCopy (pmove.velocity, originalvel);
                    263: 
                    264:        // slide move
                    265:        PM_FlyMove ();
                    266: 
                    267:        VectorCopy (pmove.origin, down);
                    268:        VectorCopy (pmove.velocity, downvel);
                    269: 
                    270:        VectorCopy (original, pmove.origin);
                    271:        VectorCopy (originalvel, pmove.velocity);
                    272: 
                    273: // move up a stair height
                    274:        VectorCopy (pmove.origin, dest);
                    275:        dest[2] += STEPSIZE;
                    276:        trace = PM_PlayerMove (pmove.origin, dest);
                    277:        if (!trace.startsolid && !trace.allsolid)
                    278:        {
                    279:                VectorCopy (trace.endpos, pmove.origin);
                    280:        }
                    281: 
                    282: // slide move
                    283:        PM_FlyMove ();
                    284: 
                    285: // press down the stepheight
                    286:        VectorCopy (pmove.origin, dest);
                    287:        dest[2] -= STEPSIZE;
                    288:        trace = PM_PlayerMove (pmove.origin, dest);
                    289:        if ( trace.plane.normal[2] < 0.7)
                    290:                goto usedown;
                    291:        if (!trace.startsolid && !trace.allsolid)
                    292:        {
                    293:                VectorCopy (trace.endpos, pmove.origin);
                    294:        }
                    295:        VectorCopy (pmove.origin, up);
                    296: 
                    297:        // decide which one went farther
                    298:        downdist = (down[0] - original[0])*(down[0] - original[0])
                    299:                + (down[1] - original[1])*(down[1] - original[1]);
                    300:        updist = (up[0] - original[0])*(up[0] - original[0])
                    301:                + (up[1] - original[1])*(up[1] - original[1]);
                    302: 
                    303:        if (downdist > updist)
                    304:        {
                    305: usedown:
                    306:                VectorCopy (down, pmove.origin);
                    307:                VectorCopy (downvel, pmove.velocity);
                    308:        } else // copy z value from slide move
                    309:                pmove.velocity[2] = downvel[2];
                    310: 
                    311: // if at a dead stop, retry the move with nudges to get around lips
                    312: 
                    313: }
                    314: 
                    315: 
                    316: 
                    317: /*
                    318: ==================
                    319: PM_Friction
                    320: 
                    321: Handles both ground friction and water friction
                    322: ==================
                    323: */
                    324: void PM_Friction (void)
                    325: {
                    326:        float   *vel;
                    327:        float   speed, newspeed, control;
                    328:        float   friction;
                    329:        float   drop;
                    330:        vec3_t  start, stop;
                    331:        pmtrace_t               trace;
                    332:        
                    333:        if (pmove.waterjumptime)
                    334:                return;
                    335: 
                    336:        vel = pmove.velocity;
                    337:        
                    338:        speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]);
                    339:        if (speed < 1)
                    340:        {
                    341:                vel[0] = 0;
                    342:                vel[1] = 0;
                    343:                return;
                    344:        }
                    345: 
                    346:        friction = movevars.friction;
                    347: 
                    348: // if the leading edge is over a dropoff, increase friction
                    349:        if (onground != -1) {
                    350:                start[0] = stop[0] = pmove.origin[0] + vel[0]/speed*16;
                    351:                start[1] = stop[1] = pmove.origin[1] + vel[1]/speed*16;
                    352:                start[2] = pmove.origin[2] + player_mins[2];
                    353:                stop[2] = start[2] - 34;
                    354: 
                    355:                trace = PM_PlayerMove (start, stop);
                    356: 
                    357:                if (trace.fraction == 1) {
                    358:                        friction *= 2;
                    359:                }
                    360:        }
                    361: 
                    362:        drop = 0;
                    363: 
                    364:        if (waterlevel >= 2) // apply water friction
                    365:                drop += speed*movevars.waterfriction*waterlevel*frametime;
                    366:        else if (onground != -1) // apply ground friction
                    367:        {
                    368:                control = speed < movevars.stopspeed ? movevars.stopspeed : speed;
                    369:                drop += control*friction*frametime;
                    370:        }
                    371: 
                    372: 
                    373: // scale the velocity
                    374:        newspeed = speed - drop;
                    375:        if (newspeed < 0)
                    376:                newspeed = 0;
                    377:        newspeed /= speed;
                    378: 
                    379:        vel[0] = vel[0] * newspeed;
                    380:        vel[1] = vel[1] * newspeed;
                    381:        vel[2] = vel[2] * newspeed;
                    382: }
                    383: 
                    384: 
                    385: /*
                    386: ==============
                    387: PM_Accelerate
                    388: ==============
                    389: */
                    390: void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel)
                    391: {
                    392:        int                     i;
                    393:        float           addspeed, accelspeed, currentspeed;
                    394: 
                    395:        if (pmove.dead)
                    396:                return;
                    397:        if (pmove.waterjumptime)
                    398:                return;
                    399: 
                    400:        currentspeed = DotProduct (pmove.velocity, wishdir);
                    401:        addspeed = wishspeed - currentspeed;
                    402:        if (addspeed <= 0)
                    403:                return;
                    404:        accelspeed = accel*frametime*wishspeed;
                    405:        if (accelspeed > addspeed)
                    406:                accelspeed = addspeed;
                    407:        
                    408:        for (i=0 ; i<3 ; i++)
                    409:                pmove.velocity[i] += accelspeed*wishdir[i];     
                    410: }
                    411: 
                    412: void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel)
                    413: {
                    414:        int                     i;
                    415:        float           addspeed, accelspeed, currentspeed, wishspd = wishspeed;
                    416:                
                    417:        if (pmove.dead)
                    418:                return;
                    419:        if (pmove.waterjumptime)
                    420:                return;
                    421: 
                    422:        if (wishspd > 30)
                    423:                wishspd = 30;
                    424:        currentspeed = DotProduct (pmove.velocity, wishdir);
                    425:        addspeed = wishspd - currentspeed;
                    426:        if (addspeed <= 0)
                    427:                return;
                    428:        accelspeed = accel * wishspeed * frametime;
                    429:        if (accelspeed > addspeed)
                    430:                accelspeed = addspeed;
                    431:        
                    432:        for (i=0 ; i<3 ; i++)
                    433:                pmove.velocity[i] += accelspeed*wishdir[i];     
                    434: }
                    435: 
                    436: 
                    437: 
                    438: /*
                    439: ===================
                    440: PM_WaterMove
                    441: 
                    442: ===================
                    443: */
                    444: void PM_WaterMove (void)
                    445: {
                    446:        int             i;
                    447:        vec3_t  wishvel;
                    448:        float   wishspeed;
                    449:        vec3_t  wishdir;
                    450:        vec3_t  start, dest;
                    451:        pmtrace_t       trace;
                    452: 
                    453: //
                    454: // user intentions
                    455: //
                    456:        for (i=0 ; i<3 ; i++)
                    457:                wishvel[i] = forward[i]*pmove.cmd.forwardmove + right[i]*pmove.cmd.sidemove;
                    458: 
                    459:        if (!pmove.cmd.forwardmove && !pmove.cmd.sidemove && !pmove.cmd.upmove)
                    460:                wishvel[2] -= 60;               // drift towards bottom
                    461:        else
                    462:                wishvel[2] += pmove.cmd.upmove;
                    463: 
                    464:        VectorCopy (wishvel, wishdir);
                    465:        wishspeed = VectorNormalize(wishdir);
                    466: 
                    467:        if (wishspeed > movevars.maxspeed)
                    468:        {
                    469:                VectorScale (wishvel, movevars.maxspeed/wishspeed, wishvel);
                    470:                wishspeed = movevars.maxspeed;
                    471:        }
                    472:        wishspeed *= 0.7;
                    473: 
                    474: //
                    475: // water acceleration
                    476: //
                    477: //     if (pmove.waterjumptime)
                    478: //             Con_Printf ("wm->%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]);
                    479:        PM_Accelerate (wishdir, wishspeed, movevars.wateraccelerate);
                    480: 
                    481: // assume it is a stair or a slope, so press down from stepheight above
                    482:        VectorMA (pmove.origin, frametime, pmove.velocity, dest);
                    483:        VectorCopy (dest, start);
                    484:        start[2] += STEPSIZE + 1;
                    485:        trace = PM_PlayerMove (start, dest);
                    486:        if (!trace.startsolid && !trace.allsolid)       // FIXME: check steep slope?
                    487:        {       // walked up the step
                    488:                VectorCopy (trace.endpos, pmove.origin);
                    489:                return;
                    490:        }
                    491:        
                    492:        PM_FlyMove ();
                    493: //     if (pmove.waterjumptime)
                    494: //             Con_Printf ("<-wm%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]);
                    495: }
                    496: 
                    497: 
                    498: /*
                    499: ===================
                    500: PM_AirMove
                    501: 
                    502: ===================
                    503: */
                    504: void PM_AirMove (void)
                    505: {
                    506:        int                     i;
                    507:        vec3_t          wishvel;
                    508:        float           fmove, smove;
                    509:        vec3_t          wishdir;
                    510:        float           wishspeed;
                    511: 
                    512:        fmove = pmove.cmd.forwardmove;
                    513:        smove = pmove.cmd.sidemove;
                    514:        
                    515:        forward[2] = 0;
                    516:        right[2] = 0;
                    517:        VectorNormalize (forward);
                    518:        VectorNormalize (right);
                    519: 
                    520:        for (i=0 ; i<2 ; i++)
                    521:                wishvel[i] = forward[i]*fmove + right[i]*smove;
                    522:        wishvel[2] = 0;
                    523: 
                    524:        VectorCopy (wishvel, wishdir);
                    525:        wishspeed = VectorNormalize(wishdir);
                    526: 
                    527: //
                    528: // clamp to server defined max speed
                    529: //
                    530:        if (wishspeed > movevars.maxspeed)
                    531:        {
                    532:                VectorScale (wishvel, movevars.maxspeed/wishspeed, wishvel);
                    533:                wishspeed = movevars.maxspeed;
                    534:        }
                    535:        
                    536: //     if (pmove.waterjumptime)
                    537: //             Con_Printf ("am->%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]);
                    538: 
                    539:        if ( onground != -1)
                    540:        {
                    541:                pmove.velocity[2] = 0;
                    542:                PM_Accelerate (wishdir, wishspeed, movevars.accelerate);
                    543:                pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime;
                    544:                PM_GroundMove ();
                    545:        }
                    546:        else
                    547:        {       // not on ground, so little effect on velocity
                    548:                PM_AirAccelerate (wishdir, wishspeed, movevars.accelerate);
                    549: 
                    550:                // add gravity
                    551:                pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime;
                    552: 
                    553:                PM_FlyMove ();
                    554: 
                    555:        }
                    556: 
                    557: //Con_Printf("airmove:vec: %4.2f %4.2f %4.2f\n",
                    558: //                     pmove.velocity[0],
                    559: //                     pmove.velocity[1],
                    560: //                     pmove.velocity[2]);
                    561: //
                    562: 
                    563: //     if (pmove.waterjumptime)
                    564: //             Con_Printf ("<-am%f, %f, %f\n", pmove.velocity[0], pmove.velocity[1], pmove.velocity[2]);
                    565: }
                    566: 
                    567: 
                    568: 
                    569: /*
                    570: =============
                    571: PM_CatagorizePosition
                    572: =============
                    573: */
                    574: void PM_CatagorizePosition (void)
                    575: {
                    576:        vec3_t          point;
                    577:        int                     cont;
                    578:        pmtrace_t               tr;
                    579: 
                    580: // if the player hull point one unit down is solid, the player
                    581: // is on ground
                    582: 
                    583: // see if standing on something solid  
                    584:        point[0] = pmove.origin[0];
                    585:        point[1] = pmove.origin[1];
                    586:        point[2] = pmove.origin[2] - 1;
                    587:        if (pmove.velocity[2] > 180)
                    588:        {
                    589:                onground = -1;
                    590:        }
                    591:        else
                    592:        {
                    593:                tr = PM_PlayerMove (pmove.origin, point);
                    594:                if ( tr.plane.normal[2] < 0.7)
                    595:                        onground = -1;  // too steep
                    596:                else
                    597:                        onground = tr.ent;
                    598:                if (onground != -1)
                    599:                {
                    600:                        pmove.waterjumptime = 0;
                    601:                        if (!tr.startsolid && !tr.allsolid)
                    602:                                VectorCopy (tr.endpos, pmove.origin);
                    603:                }
                    604: 
                    605:                // standing on an entity other than the world
                    606:                if (tr.ent > 0)
                    607:                {
                    608:                        pmove.touchindex[pmove.numtouch] = tr.ent;
                    609:                        pmove.numtouch++;
                    610:                }
                    611:        }
                    612: 
                    613: //
                    614: // get waterlevel
                    615: //
                    616:        waterlevel = 0;
                    617:        watertype = CONTENTS_EMPTY;
                    618: 
                    619:        point[2] = pmove.origin[2] + player_mins[2] + 1;        
                    620:        cont = PM_PointContents (point);
                    621: 
                    622:        if (cont <= CONTENTS_WATER)
                    623:        {
                    624:                watertype = cont;
                    625:                waterlevel = 1;
                    626:                point[2] = pmove.origin[2] + (player_mins[2] + player_maxs[2])*0.5;
                    627:                cont = PM_PointContents (point);
                    628:                if (cont <= CONTENTS_WATER)
                    629:                {
                    630:                        waterlevel = 2;
                    631:                        point[2] = pmove.origin[2] + 22;
                    632:                        cont = PM_PointContents (point);
                    633:                        if (cont <= CONTENTS_WATER)
                    634:                                waterlevel = 3;
                    635:                }
                    636:        }
                    637: }
                    638: 
                    639: 
                    640: /*
                    641: =============
                    642: JumpButton
                    643: =============
                    644: */
                    645: void JumpButton (void)
                    646: {
                    647:        if (pmove.dead)
                    648:        {
                    649:                pmove.oldbuttons |= BUTTON_JUMP;        // don't jump again until released
                    650:                return;
                    651:        }
                    652: 
                    653:        if (pmove.waterjumptime)
                    654:        {
                    655:                pmove.waterjumptime -= frametime;
                    656:                if (pmove.waterjumptime < 0)
                    657:                        pmove.waterjumptime = 0;
                    658:                return;
                    659:        }
                    660: 
                    661:        if (waterlevel >= 2)
                    662:        {       // swimming, not jumping
                    663:                onground = -1;
                    664: 
                    665:                if (watertype == CONTENTS_WATER)
                    666:                        pmove.velocity[2] = 100;
                    667:                else if (watertype == CONTENTS_SLIME)
                    668:                        pmove.velocity[2] = 80;
                    669:                else
                    670:                        pmove.velocity[2] = 50;
                    671:                return;
                    672:        }
                    673: 
                    674:        if (onground == -1)
                    675:                return;         // in air, so no effect
                    676: 
                    677:        if ( pmove.oldbuttons & BUTTON_JUMP )
                    678:                return;         // don't pogo stick
                    679: 
                    680:        onground = -1;
                    681:        pmove.velocity[2] += 270;
                    682: 
                    683:        pmove.oldbuttons |= BUTTON_JUMP;        // don't jump again until released
                    684: }
                    685: 
                    686: /*
                    687: =============
                    688: CheckWaterJump
                    689: =============
                    690: */
                    691: void CheckWaterJump (void)
                    692: {
                    693:        vec3_t  spot;
                    694:        int             cont;
                    695:        vec3_t  flatforward;
                    696: 
                    697:        if (pmove.waterjumptime)
                    698:                return;
                    699: 
                    700:        // ZOID, don't hop out if we just jumped in
                    701:        if (pmove.velocity[2] < -180)
                    702:                return; // only hop out if we are moving up
                    703: 
                    704:        // see if near an edge
                    705:        flatforward[0] = forward[0];
                    706:        flatforward[1] = forward[1];
                    707:        flatforward[2] = 0;
                    708:        VectorNormalize (flatforward);
                    709: 
                    710:        VectorMA (pmove.origin, 24, flatforward, spot);
                    711:        spot[2] += 8;
                    712:        cont = PM_PointContents (spot);
                    713:        if (cont != CONTENTS_SOLID)
                    714:                return;
                    715:        spot[2] += 24;
                    716:        cont = PM_PointContents (spot);
                    717:        if (cont != CONTENTS_EMPTY)
                    718:                return;
                    719:        // jump out of water
                    720:        VectorScale (flatforward, 50, pmove.velocity);
                    721:        pmove.velocity[2] = 310;
                    722:        pmove.waterjumptime = 2;        // safety net
                    723:        pmove.oldbuttons |= BUTTON_JUMP;        // don't jump again until released
                    724: }
                    725: 
                    726: /*
                    727: =================
                    728: NudgePosition
                    729: 
                    730: If pmove.origin is in a solid position,
                    731: try nudging slightly on all axis to
                    732: allow for the cut precision of the net coordinates
                    733: =================
                    734: */
                    735: void NudgePosition (void)
                    736: {
                    737:        vec3_t  base;
                    738:        int             x, y, z;
                    739:        int             i;
                    740:        static int              sign[3] = {0, -1, 1};
                    741: 
                    742:        VectorCopy (pmove.origin, base);
                    743: 
                    744:        for (i=0 ; i<3 ; i++)
                    745:                pmove.origin[i] = ((int)(pmove.origin[i]*8)) * 0.125;
                    746: //     pmove.origin[2] += 0.124;
                    747: 
                    748: //     if (pmove.dead)
                    749: //             return;         // might be a squished point, so don'y bother
                    750: //     if (PM_TestPlayerPosition (pmove.origin) )
                    751: //             return;
                    752: 
                    753:        for (z=0 ; z<=2 ; z++)
                    754:        {
                    755:                for (x=0 ; x<=2 ; x++)
                    756:                {
                    757:                        for (y=0 ; y<=2 ; y++)
                    758:                        {
                    759:                                pmove.origin[0] = base[0] + (sign[x] * 1.0/8);
                    760:                                pmove.origin[1] = base[1] + (sign[y] * 1.0/8);
                    761:                                pmove.origin[2] = base[2] + (sign[z] * 1.0/8);
                    762:                                if (PM_TestPlayerPosition (pmove.origin))
                    763:                                        return;
                    764:                        }
                    765:                }
                    766:        }
                    767:        VectorCopy (base, pmove.origin);
                    768: //     Con_DPrintf ("NudgePosition: stuck\n");
                    769: }
                    770: 
                    771: /*
                    772: ===============
                    773: SpectatorMove
                    774: ===============
                    775: */
                    776: void SpectatorMove (void)
                    777: {
                    778:        float   speed, drop, friction, control, newspeed, accel;
                    779:        float   currentspeed, addspeed, accelspeed;
                    780:        int                     i;
                    781:        vec3_t          wishvel;
                    782:        float           fmove, smove;
                    783:        vec3_t          wishdir;
                    784:        float           wishspeed;
                    785: #ifndef SERVERONLY
                    786:        extern float    server_version; // version of server we connected to
                    787: #endif
                    788: 
                    789:        // friction
                    790: 
                    791:        speed = Length (pmove.velocity);
                    792:        if (speed < 1)
                    793:        {
                    794:                VectorCopy (vec3_origin, pmove.velocity)
                    795:        }
                    796:        else
                    797:        {
                    798:                drop = 0;
                    799: 
                    800:                friction = movevars.friction*1.5;       // extra friction
                    801:                control = speed < movevars.stopspeed ? movevars.stopspeed : speed;
                    802:                drop += control*friction*frametime;
                    803: 
                    804:                // scale the velocity
                    805:                newspeed = speed - drop;
                    806:                if (newspeed < 0)
                    807:                        newspeed = 0;
                    808:                newspeed /= speed;
                    809: 
                    810:                VectorScale (pmove.velocity, newspeed, pmove.velocity);
                    811:        }
                    812: 
                    813:        // accelerate
                    814:        fmove = pmove.cmd.forwardmove;
                    815:        smove = pmove.cmd.sidemove;
                    816:        
                    817:        VectorNormalize (forward);
                    818:        VectorNormalize (right);
                    819: 
                    820:        for (i=0 ; i<3 ; i++)
                    821:                wishvel[i] = forward[i]*fmove + right[i]*smove;
                    822:        wishvel[2] += pmove.cmd.upmove;
                    823: 
                    824:        VectorCopy (wishvel, wishdir);
                    825:        wishspeed = VectorNormalize(wishdir);
                    826: 
                    827:        //
                    828:        // clamp to server defined max speed
                    829:        //
                    830:        if (wishspeed > movevars.spectatormaxspeed)
                    831:        {
                    832:                VectorScale (wishvel, movevars.spectatormaxspeed/wishspeed, wishvel);
                    833:                wishspeed = movevars.spectatormaxspeed;
                    834:        }
                    835: 
                    836:        currentspeed = DotProduct(pmove.velocity, wishdir);
                    837:        addspeed = wishspeed - currentspeed;
                    838:        if (addspeed <= 0)
                    839:                return;
                    840:        accelspeed = movevars.accelerate*frametime*wishspeed;
                    841:        if (accelspeed > addspeed)
                    842:                accelspeed = addspeed;
                    843:        
                    844:        for (i=0 ; i<3 ; i++)
                    845:                pmove.velocity[i] += accelspeed*wishdir[i];     
                    846: 
                    847: 
                    848:        // move
                    849:        VectorMA (pmove.origin, frametime, pmove.velocity, pmove.origin);
                    850: }
                    851: 
                    852: /*
                    853: =============
                    854: PlayerMove
                    855: 
                    856: Returns with origin, angles, and velocity modified in place.
                    857: 
                    858: Numtouch and touchindex[] will be set if any of the physents
                    859: were contacted during the move.
                    860: =============
                    861: */
                    862: void PlayerMove (void)
                    863: {
                    864:        frametime = pmove.cmd.msec * 0.001;
                    865:        pmove.numtouch = 0;
                    866: 
                    867:        AngleVectors (pmove.angles, forward, right, up);
                    868: 
                    869:        if (pmove.spectator)
                    870:        {
                    871:                SpectatorMove ();
                    872:                return;
                    873:        }
                    874: 
                    875:        NudgePosition ();
                    876: 
                    877:        // take angles directly from command
                    878:        VectorCopy (pmove.cmd.angles, pmove.angles);
                    879: 
                    880:        // set onground, watertype, and waterlevel
                    881:        PM_CatagorizePosition ();
                    882: 
                    883:        if (waterlevel == 2)
                    884:                CheckWaterJump ();
                    885: 
                    886:        if (pmove.velocity[2] < 0)
                    887:                pmove.waterjumptime = 0;
                    888: 
                    889:        if (pmove.cmd.buttons & BUTTON_JUMP)
                    890:                JumpButton ();
                    891:        else
                    892:                pmove.oldbuttons &= ~BUTTON_JUMP;
                    893: 
                    894:        PM_Friction ();
                    895: 
                    896:        if (waterlevel >= 2)
                    897:                PM_WaterMove ();
                    898:        else
                    899:                PM_AirMove ();
                    900: 
                    901:        // set onground, watertype, and waterlevel for final spot
                    902:        PM_CatagorizePosition ();
                    903: }
                    904: 

unix.superglobalmegacorp.com

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