Annotation of quakeworld/client/pmove.c, revision 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.