Annotation of quakeworld/server/sv_phys.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: // sv_phys.c
                     21: 
                     22: #include "qwsvdef.h"
                     23: 
                     24: /*
                     25: 
                     26: 
                     27: pushmove objects do not obey gravity, and do not interact with each other or trigger fields, but block normal movement and push normal objects when they move.
                     28: 
                     29: onground is set for toss objects when they come to a complete rest.  it is set for steping or walking objects 
                     30: 
                     31: doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH
                     32: bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS
                     33: corpses are SOLID_NOT and MOVETYPE_TOSS
                     34: crates are SOLID_BBOX and MOVETYPE_TOSS
                     35: walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP
                     36: flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY
                     37: 
                     38: solid_edge items only clip against bsp models.
                     39: 
                     40: */
                     41: 
                     42: cvar_t sv_maxvelocity = {"sv_maxvelocity","2000"}; 
                     43: 
                     44: cvar_t sv_gravity                       = { "sv_gravity", "800"};    
                     45: cvar_t sv_stopspeed             = { "sv_stopspeed", "100"};    
                     46: cvar_t sv_maxspeed                      = { "sv_maxspeed", "320"};    
                     47: cvar_t sv_spectatormaxspeed = { "sv_spectatormaxspeed", "500"};
                     48: cvar_t sv_accelerate            = { "sv_accelerate", "10"};     
                     49: cvar_t sv_airaccelerate         = { "sv_airaccelerate", "0.7"};    
                     50: cvar_t sv_wateraccelerate       = { "sv_wateraccelerate", "10"};     
                     51: cvar_t sv_friction                      = { "sv_friction", "4"};      
                     52: cvar_t sv_waterfriction         = { "sv_waterfriction", "4"};      
                     53: 
                     54: 
                     55: #define        MOVE_EPSILON    0.01
                     56: 
                     57: void SV_Physics_Toss (edict_t *ent);
                     58: 
                     59: /*
                     60: ================
                     61: SV_CheckAllEnts
                     62: ================
                     63: */
                     64: void SV_CheckAllEnts (void)
                     65: {
                     66:        int                     e;
                     67:        edict_t         *check;
                     68: 
                     69: // see if any solid entities are inside the final position
                     70:        check = NEXT_EDICT(sv.edicts);
                     71:        for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
                     72:        {
                     73:                if (check->free)
                     74:                        continue;
                     75:                if (check->v.movetype == MOVETYPE_PUSH
                     76:                || check->v.movetype == MOVETYPE_NONE
                     77:                || check->v.movetype == MOVETYPE_NOCLIP)
                     78:                        continue;
                     79: 
                     80:                if (SV_TestEntityPosition (check))
                     81:                        Con_Printf ("entity in invalid position\n");
                     82:        }
                     83: }
                     84: 
                     85: /*
                     86: ================
                     87: SV_CheckVelocity
                     88: ================
                     89: */
                     90: void SV_CheckVelocity (edict_t *ent)
                     91: {
                     92:        int             i;
                     93: 
                     94: //
                     95: // bound velocity
                     96: //
                     97:        for (i=0 ; i<3 ; i++)
                     98:        {
                     99:                if (IS_NAN(ent->v.velocity[i]))
                    100:                {
                    101:                        Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(ent->v.classname));
                    102:                        ent->v.velocity[i] = 0;
                    103:                }
                    104:                if (IS_NAN(ent->v.origin[i]))
                    105:                {
                    106:                        Con_Printf ("Got a NaN origin on %s\n", PR_GetString(ent->v.classname));
                    107:                        ent->v.origin[i] = 0;
                    108:                }
                    109:                if (ent->v.velocity[i] > sv_maxvelocity.value)
                    110:                        ent->v.velocity[i] = sv_maxvelocity.value;
                    111:                else if (ent->v.velocity[i] < -sv_maxvelocity.value)
                    112:                        ent->v.velocity[i] = -sv_maxvelocity.value;
                    113:        }
                    114: }
                    115: 
                    116: /*
                    117: =============
                    118: SV_RunThink
                    119: 
                    120: Runs thinking code if time.  There is some play in the exact time the think
                    121: function will be called, because it is called before any movement is done
                    122: in a frame.  Not used for pushmove objects, because they must be exact.
                    123: Returns false if the entity removed itself.
                    124: =============
                    125: */
                    126: qboolean SV_RunThink (edict_t *ent)
                    127: {
                    128:        float   thinktime;
                    129: 
                    130:        do
                    131:        {
                    132:                thinktime = ent->v.nextthink;
                    133:                if (thinktime <= 0)
                    134:                        return true;
                    135:                if (thinktime > sv.time + host_frametime)
                    136:                        return true;
                    137:                
                    138:                if (thinktime < sv.time)
                    139:                        thinktime = sv.time;    // don't let things stay in the past.
                    140:                                                                        // it is possible to start that way
                    141:                                                                        // by a trigger with a local time.
                    142:                ent->v.nextthink = 0;
                    143:                pr_global_struct->time = thinktime;
                    144:                pr_global_struct->self = EDICT_TO_PROG(ent);
                    145:                pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
                    146:                PR_ExecuteProgram (ent->v.think);
                    147: 
                    148:                if (ent->free)
                    149:                        return false;
                    150:        } while (1);
                    151: 
                    152:        return true;
                    153: }
                    154: 
                    155: /*
                    156: ==================
                    157: SV_Impact
                    158: 
                    159: Two entities have touched, so run their touch functions
                    160: ==================
                    161: */
                    162: void SV_Impact (edict_t *e1, edict_t *e2)
                    163: {
                    164:        int             old_self, old_other;
                    165:        
                    166:        old_self = pr_global_struct->self;
                    167:        old_other = pr_global_struct->other;
                    168:        
                    169:        pr_global_struct->time = sv.time;
                    170:        if (e1->v.touch && e1->v.solid != SOLID_NOT)
                    171:        {
                    172:                pr_global_struct->self = EDICT_TO_PROG(e1);
                    173:                pr_global_struct->other = EDICT_TO_PROG(e2);
                    174:                PR_ExecuteProgram (e1->v.touch);
                    175:        }
                    176:        
                    177:        if (e2->v.touch && e2->v.solid != SOLID_NOT)
                    178:        {
                    179:                pr_global_struct->self = EDICT_TO_PROG(e2);
                    180:                pr_global_struct->other = EDICT_TO_PROG(e1);
                    181:                PR_ExecuteProgram (e2->v.touch);
                    182:        }
                    183: 
                    184:        pr_global_struct->self = old_self;
                    185:        pr_global_struct->other = old_other;
                    186: }
                    187: 
                    188: 
                    189: /*
                    190: ==================
                    191: ClipVelocity
                    192: 
                    193: Slide off of the impacting object
                    194: returns the blocked flags (1 = floor, 2 = step / wall)
                    195: ==================
                    196: */
                    197: #define        STOP_EPSILON    0.1
                    198: 
                    199: int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
                    200: {
                    201:        float   backoff;
                    202:        float   change;
                    203:        int             i, blocked;
                    204:        
                    205:        blocked = 0;
                    206:        if (normal[2] > 0)
                    207:                blocked |= 1;           // floor
                    208:        if (!normal[2])
                    209:                blocked |= 2;           // step
                    210:        
                    211:        backoff = DotProduct (in, normal) * overbounce;
                    212: 
                    213:        for (i=0 ; i<3 ; i++)
                    214:        {
                    215:                change = normal[i]*backoff;
                    216:                out[i] = in[i] - change;
                    217:                if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON)
                    218:                        out[i] = 0;
                    219:        }
                    220:        
                    221:        return blocked;
                    222: }
                    223: 
                    224: 
                    225: /*
                    226: ============
                    227: SV_FlyMove
                    228: 
                    229: The basic solid body movement clip that slides along multiple planes
                    230: Returns the clipflags if the velocity was modified (hit something solid)
                    231: 1 = floor
                    232: 2 = wall / step
                    233: 4 = dead stop
                    234: If steptrace is not NULL, the trace of any vertical wall hit will be stored
                    235: ============
                    236: */
                    237: #define        MAX_CLIP_PLANES 5
                    238: int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
                    239: {
                    240:        int                     bumpcount, numbumps;
                    241:        vec3_t          dir;
                    242:        float           d;
                    243:        int                     numplanes;
                    244:        vec3_t          planes[MAX_CLIP_PLANES];
                    245:        vec3_t          primal_velocity, original_velocity, new_velocity;
                    246:        int                     i, j;
                    247:        trace_t         trace;
                    248:        vec3_t          end;
                    249:        float           time_left;
                    250:        int                     blocked;
                    251:        
                    252:        numbumps = 4;
                    253:        
                    254:        blocked = 0;
                    255:        VectorCopy (ent->v.velocity, original_velocity);
                    256:        VectorCopy (ent->v.velocity, primal_velocity);
                    257:        numplanes = 0;
                    258:        
                    259:        time_left = time;
                    260: 
                    261:        for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
                    262:        {
                    263:                for (i=0 ; i<3 ; i++)
                    264:                        end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i];
                    265: 
                    266:                trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);
                    267: 
                    268:                if (trace.allsolid)
                    269:                {       // entity is trapped in another solid
                    270:                        VectorCopy (vec3_origin, ent->v.velocity);
                    271:                        return 3;
                    272:                }
                    273: 
                    274:                if (trace.fraction > 0)
                    275:                {       // actually covered some distance
                    276:                        VectorCopy (trace.endpos, ent->v.origin);
                    277:                        VectorCopy (ent->v.velocity, original_velocity);
                    278:                        numplanes = 0;
                    279:                }
                    280: 
                    281:                if (trace.fraction == 1)
                    282:                         break;         // moved the entire distance
                    283: 
                    284:                if (!trace.ent)
                    285:                        SV_Error ("SV_FlyMove: !trace.ent");
                    286: 
                    287:                if (trace.plane.normal[2] > 0.7)
                    288:                {
                    289:                        blocked |= 1;           // floor
                    290:                        if (trace.ent->v.solid == SOLID_BSP)
                    291:                        {
                    292:                                ent->v.flags =  (int)ent->v.flags | FL_ONGROUND;
                    293:                                ent->v.groundentity = EDICT_TO_PROG(trace.ent);
                    294:                        }
                    295:                }
                    296:                if (!trace.plane.normal[2])
                    297:                {
                    298:                        blocked |= 2;           // step
                    299:                        if (steptrace)
                    300:                                *steptrace = trace;     // save for player extrafriction
                    301:                }
                    302: 
                    303: //
                    304: // run the impact function
                    305: //
                    306:                SV_Impact (ent, trace.ent);
                    307:                if (ent->free)
                    308:                        break;          // removed by the impact function
                    309: 
                    310:                
                    311:                time_left -= time_left * trace.fraction;
                    312:                
                    313:        // cliped to another plane
                    314:                if (numplanes >= MAX_CLIP_PLANES)
                    315:                {       // this shouldn't really happen
                    316:                        VectorCopy (vec3_origin, ent->v.velocity);
                    317:                        return 3;
                    318:                }
                    319: 
                    320:                VectorCopy (trace.plane.normal, planes[numplanes]);
                    321:                numplanes++;
                    322: 
                    323: //
                    324: // modify original_velocity so it parallels all of the clip planes
                    325: //
                    326:                for (i=0 ; i<numplanes ; i++)
                    327:                {
                    328:                        ClipVelocity (original_velocity, planes[i], new_velocity, 1);
                    329:                        for (j=0 ; j<numplanes ; j++)
                    330:                                if (j != i)
                    331:                                {
                    332:                                        if (DotProduct (new_velocity, planes[j]) < 0)
                    333:                                                break;  // not ok
                    334:                                }
                    335:                        if (j == numplanes)
                    336:                                break;
                    337:                }
                    338:                
                    339:                if (i != numplanes)
                    340:                {       // go along this plane
                    341:                        VectorCopy (new_velocity, ent->v.velocity);
                    342:                }
                    343:                else
                    344:                {       // go along the crease
                    345:                        if (numplanes != 2)
                    346:                        {
                    347: //                             Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
                    348:                                VectorCopy (vec3_origin, ent->v.velocity);
                    349:                                return 7;
                    350:                        }
                    351:                        CrossProduct (planes[0], planes[1], dir);
                    352:                        d = DotProduct (dir, ent->v.velocity);
                    353:                        VectorScale (dir, d, ent->v.velocity);
                    354:                }
                    355: 
                    356: //
                    357: // if original velocity is against the original velocity, stop dead
                    358: // to avoid tiny occilations in sloping corners
                    359: //
                    360:                if (DotProduct (ent->v.velocity, primal_velocity) <= 0)
                    361:                {
                    362:                        VectorCopy (vec3_origin, ent->v.velocity);
                    363:                        return blocked;
                    364:                }
                    365:        }
                    366: 
                    367:        return blocked;
                    368: }
                    369: 
                    370: 
                    371: /*
                    372: ============
                    373: SV_AddGravity
                    374: 
                    375: ============
                    376: */
                    377: void SV_AddGravity (edict_t *ent, float scale)
                    378: {
                    379:        ent->v.velocity[2] -= scale * movevars.gravity * host_frametime;
                    380: }
                    381: 
                    382: /*
                    383: ===============================================================================
                    384: 
                    385: PUSHMOVE
                    386: 
                    387: ===============================================================================
                    388: */
                    389: 
                    390: /*
                    391: ============
                    392: SV_PushEntity
                    393: 
                    394: Does not change the entities velocity at all
                    395: ============
                    396: */
                    397: trace_t SV_PushEntity (edict_t *ent, vec3_t push)
                    398: {
                    399:        trace_t trace;
                    400:        vec3_t  end;
                    401:                
                    402:        VectorAdd (ent->v.origin, push, end);
                    403: 
                    404:        if (ent->v.movetype == MOVETYPE_FLYMISSILE)
                    405:                trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent);
                    406:        else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT)
                    407:        // only clip against bmodels
                    408:                trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NOMONSTERS, ent);
                    409:        else
                    410:                trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
                    411:        
                    412:        VectorCopy (trace.endpos, ent->v.origin);
                    413:        SV_LinkEdict (ent, true);
                    414: 
                    415:        if (trace.ent)
                    416:                SV_Impact (ent, trace.ent);             
                    417: 
                    418:        return trace;
                    419: }                                      
                    420: 
                    421: 
                    422: /*
                    423: ============
                    424: SV_Push
                    425: 
                    426: ============
                    427: */
                    428: qboolean SV_Push (edict_t *pusher, vec3_t move)
                    429: {
                    430:        int                     i, e;
                    431:        edict_t         *check, *block;
                    432:        vec3_t          mins, maxs;
                    433:        vec3_t          pushorig;
                    434:        int                     num_moved;
                    435:        edict_t         *moved_edict[MAX_EDICTS];
                    436:        vec3_t          moved_from[MAX_EDICTS];
                    437: 
                    438:        for (i=0 ; i<3 ; i++)
                    439:        {
                    440:                mins[i] = pusher->v.absmin[i] + move[i];
                    441:                maxs[i] = pusher->v.absmax[i] + move[i];
                    442:        }
                    443: 
                    444:        VectorCopy (pusher->v.origin, pushorig);
                    445:        
                    446: // move the pusher to it's final position
                    447: 
                    448:        VectorAdd (pusher->v.origin, move, pusher->v.origin);
                    449:        SV_LinkEdict (pusher, false);
                    450: 
                    451: // see if any solid entities are inside the final position
                    452:        num_moved = 0;
                    453:        check = NEXT_EDICT(sv.edicts);
                    454:        for (e=1 ; e<sv.num_edicts ; e++, check = NEXT_EDICT(check))
                    455:        {
                    456:                if (check->free)
                    457:                        continue;
                    458:                if (check->v.movetype == MOVETYPE_PUSH
                    459:                || check->v.movetype == MOVETYPE_NONE
                    460:                || check->v.movetype == MOVETYPE_NOCLIP)
                    461:                        continue;
                    462: 
                    463:                pusher->v.solid = SOLID_NOT;
                    464:                block = SV_TestEntityPosition (check);
                    465:                pusher->v.solid = SOLID_BSP;
                    466:                if (block)
                    467:                        continue;
                    468: 
                    469:        // if the entity is standing on the pusher, it will definately be moved
                    470:                if ( ! ( ((int)check->v.flags & FL_ONGROUND)
                    471:                && PROG_TO_EDICT(check->v.groundentity) == pusher) )
                    472:                {
                    473:                        if ( check->v.absmin[0] >= maxs[0]
                    474:                        || check->v.absmin[1] >= maxs[1]
                    475:                        || check->v.absmin[2] >= maxs[2]
                    476:                        || check->v.absmax[0] <= mins[0]
                    477:                        || check->v.absmax[1] <= mins[1]
                    478:                        || check->v.absmax[2] <= mins[2] )
                    479:                                continue;
                    480: 
                    481:                // see if the ent's bbox is inside the pusher's final position
                    482:                        if (!SV_TestEntityPosition (check))
                    483:                                continue;
                    484:                }
                    485: 
                    486:                VectorCopy (check->v.origin, moved_from[num_moved]);
                    487:                moved_edict[num_moved] = check;
                    488:                num_moved++;
                    489: 
                    490:                // try moving the contacted entity 
                    491:                VectorAdd (check->v.origin, move, check->v.origin);
                    492:                block = SV_TestEntityPosition (check);
                    493:                if (!block)
                    494:                {       // pushed ok
                    495:                        SV_LinkEdict (check, false);
                    496:                        continue;
                    497:                }
                    498: 
                    499:                // if it is ok to leave in the old position, do it
                    500:                VectorSubtract (check->v.origin, move, check->v.origin);
                    501:                block = SV_TestEntityPosition (check);
                    502:                if (!block)
                    503:                {
                    504:                        num_moved--;
                    505:                        continue;
                    506:                }
                    507: 
                    508:        // if it is still inside the pusher, block
                    509:                if (check->v.mins[0] == check->v.maxs[0])
                    510:                {
                    511:                        SV_LinkEdict (check, false);
                    512:                        continue;
                    513:                }
                    514:                if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER)
                    515:                {       // corpse
                    516:                        check->v.mins[0] = check->v.mins[1] = 0;
                    517:                        VectorCopy (check->v.mins, check->v.maxs);
                    518:                        SV_LinkEdict (check, false);
                    519:                        continue;
                    520:                }
                    521:                
                    522:                VectorCopy (pushorig, pusher->v.origin);
                    523:                SV_LinkEdict (pusher, false);
                    524: 
                    525:                // if the pusher has a "blocked" function, call it
                    526:                // otherwise, just stay in place until the obstacle is gone
                    527:                if (pusher->v.blocked)
                    528:                {
                    529:                        pr_global_struct->self = EDICT_TO_PROG(pusher);
                    530:                        pr_global_struct->other = EDICT_TO_PROG(check);
                    531:                        PR_ExecuteProgram (pusher->v.blocked);
                    532:                }
                    533:                
                    534:        // move back any entities we already moved
                    535:                for (i=0 ; i<num_moved ; i++)
                    536:                {
                    537:                        VectorCopy (moved_from[i], moved_edict[i]->v.origin);
                    538:                        SV_LinkEdict (moved_edict[i], false);
                    539:                }
                    540:                return false;
                    541:        }
                    542: 
                    543:        return true;
                    544: }
                    545: 
                    546: /*
                    547: ============
                    548: SV_PushMove
                    549: 
                    550: ============
                    551: */
                    552: void SV_PushMove (edict_t *pusher, float movetime)
                    553: {
                    554:        int                     i;
                    555:        vec3_t          move;
                    556: 
                    557:        if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
                    558:        {
                    559:                pusher->v.ltime += movetime;
                    560:                return;
                    561:        }
                    562: 
                    563:        for (i=0 ; i<3 ; i++)
                    564:                move[i] = pusher->v.velocity[i] * movetime;
                    565: 
                    566:        if (SV_Push (pusher, move))
                    567:                pusher->v.ltime += movetime;
                    568: }
                    569: 
                    570: 
                    571: /*
                    572: ================
                    573: SV_Physics_Pusher
                    574: 
                    575: ================
                    576: */
                    577: void SV_Physics_Pusher (edict_t *ent)
                    578: {
                    579:        float   thinktime;
                    580:        float   oldltime;
                    581:        float   movetime;
                    582: vec3_t oldorg, move;
                    583: float  l;
                    584: 
                    585:        oldltime = ent->v.ltime;
                    586:        
                    587:        thinktime = ent->v.nextthink;
                    588:        if (thinktime < ent->v.ltime + host_frametime)
                    589:        {
                    590:                movetime = thinktime - ent->v.ltime;
                    591:                if (movetime < 0)
                    592:                        movetime = 0;
                    593:        }
                    594:        else
                    595:                movetime = host_frametime;
                    596: 
                    597:        if (movetime)
                    598:        {
                    599:                SV_PushMove (ent, movetime);    // advances ent->v.ltime if not blocked
                    600:        }
                    601:                
                    602:        if (thinktime > oldltime && thinktime <= ent->v.ltime)
                    603:        {
                    604: VectorCopy (ent->v.origin, oldorg);
                    605:                ent->v.nextthink = 0;
                    606:                pr_global_struct->time = sv.time;
                    607:                pr_global_struct->self = EDICT_TO_PROG(ent);
                    608:                pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
                    609:                PR_ExecuteProgram (ent->v.think);
                    610:                if (ent->free)
                    611:                        return;
                    612: VectorSubtract (ent->v.origin, oldorg, move);
                    613: 
                    614: l = Length(move);
                    615: if (l > 1.0/64)
                    616: {
                    617: //     Con_Printf ("**** snap: %f\n", Length (l));
                    618:        VectorCopy (oldorg, ent->v.origin);
                    619:        SV_Push (ent, move);
                    620: }
                    621: 
                    622:        }
                    623: 
                    624: }
                    625: 
                    626: 
                    627: /*
                    628: =============
                    629: SV_Physics_None
                    630: 
                    631: Non moving objects can only think
                    632: =============
                    633: */
                    634: void SV_Physics_None (edict_t *ent)
                    635: {
                    636: // regular thinking
                    637:        SV_RunThink (ent);
                    638: }
                    639: 
                    640: /*
                    641: =============
                    642: SV_Physics_Noclip
                    643: 
                    644: A moving object that doesn't obey physics
                    645: =============
                    646: */
                    647: void SV_Physics_Noclip (edict_t *ent)
                    648: {
                    649: // regular thinking
                    650:        if (!SV_RunThink (ent))
                    651:                return;
                    652:        
                    653:        VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
                    654:        VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin);
                    655: 
                    656:        SV_LinkEdict (ent, false);
                    657: }
                    658: 
                    659: /*
                    660: ==============================================================================
                    661: 
                    662: TOSS / BOUNCE
                    663: 
                    664: ==============================================================================
                    665: */
                    666: 
                    667: /*
                    668: =============
                    669: SV_CheckWaterTransition
                    670: 
                    671: =============
                    672: */
                    673: void SV_CheckWaterTransition (edict_t *ent)
                    674: {
                    675:        int             cont;
                    676: 
                    677:        cont = SV_PointContents (ent->v.origin);
                    678:        if (!ent->v.watertype)
                    679:        {       // just spawned here
                    680:                ent->v.watertype = cont;
                    681:                ent->v.waterlevel = 1;
                    682:                return;
                    683:        }
                    684:        
                    685:        if (cont <= CONTENTS_WATER)
                    686:        {
                    687:                if (ent->v.watertype == CONTENTS_EMPTY)
                    688:                {       // just crossed into water
                    689:                        SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
                    690:                }               
                    691:                ent->v.watertype = cont;
                    692:                ent->v.waterlevel = 1;
                    693:        }
                    694:        else
                    695:        {
                    696:                if (ent->v.watertype != CONTENTS_EMPTY)
                    697:                {       // just crossed into water
                    698:                        SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
                    699:                }               
                    700:                ent->v.watertype = CONTENTS_EMPTY;
                    701:                ent->v.waterlevel = cont;
                    702:        }
                    703: }
                    704: 
                    705: /*
                    706: =============
                    707: SV_Physics_Toss
                    708: 
                    709: Toss, bounce, and fly movement.  When onground, do nothing.
                    710: =============
                    711: */
                    712: void SV_Physics_Toss (edict_t *ent)
                    713: {
                    714:        trace_t trace;
                    715:        vec3_t  move;
                    716:        float   backoff;
                    717: 
                    718: // regular thinking
                    719:        if (!SV_RunThink (ent))
                    720:                return;
                    721: 
                    722:        if (ent->v.velocity[2] > 0)
                    723:                ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
                    724: 
                    725: // if onground, return without moving
                    726:        if ( ((int)ent->v.flags & FL_ONGROUND) )
                    727:                return;
                    728: 
                    729:        SV_CheckVelocity (ent);
                    730: 
                    731: // add gravity
                    732:        if (ent->v.movetype != MOVETYPE_FLY
                    733:        && ent->v.movetype != MOVETYPE_FLYMISSILE)
                    734:                SV_AddGravity (ent, 1.0);
                    735: 
                    736: // move angles
                    737:        VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles);
                    738: 
                    739: // move origin
                    740:        VectorScale (ent->v.velocity, host_frametime, move);
                    741:        trace = SV_PushEntity (ent, move);
                    742:        if (trace.fraction == 1)
                    743:                return;
                    744:        if (ent->free)
                    745:                return;
                    746:        
                    747:        if (ent->v.movetype == MOVETYPE_BOUNCE)
                    748:                backoff = 1.5;
                    749:        else
                    750:                backoff = 1;
                    751: 
                    752:        ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff);
                    753: 
                    754: // stop if on ground
                    755:        if (trace.plane.normal[2] > 0.7)
                    756:        {               
                    757:                if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE )
                    758:                {
                    759:                        ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
                    760:                        ent->v.groundentity = EDICT_TO_PROG(trace.ent);
                    761:                        VectorCopy (vec3_origin, ent->v.velocity);
                    762:                        VectorCopy (vec3_origin, ent->v.avelocity);
                    763:                }
                    764:        }
                    765:        
                    766: // check for in water
                    767:        SV_CheckWaterTransition (ent);
                    768: }
                    769: 
                    770: /*
                    771: ===============================================================================
                    772: 
                    773: STEPPING MOVEMENT
                    774: 
                    775: ===============================================================================
                    776: */
                    777: 
                    778: /*
                    779: =============
                    780: SV_Physics_Step
                    781: 
                    782: Monsters freefall when they don't have a ground entity, otherwise
                    783: all movement is done with discrete steps.
                    784: 
                    785: This is also used for objects that have become still on the ground, but
                    786: will fall if the floor is pulled out from under them.
                    787: FIXME: is this true?
                    788: =============
                    789: */
                    790: void SV_Physics_Step (edict_t *ent)
                    791: {
                    792:        qboolean        hitsound;
                    793: 
                    794: // frefall if not onground
                    795:        if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) )
                    796:        {
                    797:                if (ent->v.velocity[2] < movevars.gravity*-0.1)
                    798:                        hitsound = true;
                    799:                else
                    800:                        hitsound = false;
                    801: 
                    802:                SV_AddGravity (ent, 1.0);
                    803:                SV_CheckVelocity (ent);
                    804:                SV_FlyMove (ent, host_frametime, NULL);
                    805:                SV_LinkEdict (ent, true);
                    806: 
                    807:                if ( (int)ent->v.flags & FL_ONGROUND )  // just hit ground
                    808:                {
                    809:                        if (hitsound)
                    810:                                SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
                    811:                }
                    812:        }
                    813: 
                    814: // regular thinking
                    815:        SV_RunThink (ent);
                    816:        
                    817:        SV_CheckWaterTransition (ent);
                    818: }
                    819: 
                    820: //============================================================================
                    821: 
                    822: void SV_ProgStartFrame (void)
                    823: {
                    824: // let the progs know that a new frame has started
                    825:        pr_global_struct->self = EDICT_TO_PROG(sv.edicts);
                    826:        pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
                    827:        pr_global_struct->time = sv.time;
                    828:        PR_ExecuteProgram (pr_global_struct->StartFrame);
                    829: }
                    830: 
                    831: /*
                    832: ================
                    833: SV_RunEntity
                    834: 
                    835: ================
                    836: */
                    837: void SV_RunEntity (edict_t *ent)
                    838: {
                    839:        if (ent->v.lastruntime == (float)realtime)
                    840:                return;
                    841:        ent->v.lastruntime = (float)realtime;
                    842: 
                    843:        switch ( (int)ent->v.movetype)
                    844:        {
                    845:        case MOVETYPE_PUSH:
                    846:                SV_Physics_Pusher (ent);
                    847:                break;
                    848:        case MOVETYPE_NONE:
                    849:                SV_Physics_None (ent);
                    850:                break;
                    851:        case MOVETYPE_NOCLIP:
                    852:                SV_Physics_Noclip (ent);
                    853:                break;
                    854:        case MOVETYPE_STEP:
                    855:                SV_Physics_Step (ent);
                    856:                break;
                    857:        case MOVETYPE_TOSS:
                    858:        case MOVETYPE_BOUNCE:
                    859:        case MOVETYPE_FLY:
                    860:        case MOVETYPE_FLYMISSILE:
                    861:                SV_Physics_Toss (ent);
                    862:                break;
                    863:        default:
                    864:                SV_Error ("SV_Physics: bad movetype %i", (int)ent->v.movetype);                 
                    865:        }
                    866: }
                    867: 
                    868: /*
                    869: ================
                    870: SV_RunNewmis
                    871: 
                    872: ================
                    873: */
                    874: void SV_RunNewmis (void)
                    875: {
                    876:        edict_t *ent;
                    877: 
                    878:        if (!pr_global_struct->newmis)
                    879:                return;
                    880:        ent = PROG_TO_EDICT(pr_global_struct->newmis);
                    881:        host_frametime = 0.05;
                    882:        pr_global_struct->newmis = 0;
                    883:        
                    884:        SV_RunEntity (ent);             
                    885: }
                    886: 
                    887: /*
                    888: ================
                    889: SV_Physics
                    890: 
                    891: ================
                    892: */
                    893: void SV_Physics (void)
                    894: {
                    895:        int             i;
                    896:        edict_t *ent;
                    897:        static double   old_time;
                    898: 
                    899: // don't bother running a frame if sys_ticrate seconds haven't passed
                    900:        host_frametime = realtime - old_time;
                    901:        if (host_frametime < sv_mintic.value)
                    902:                return;
                    903:        if (host_frametime > sv_maxtic.value)
                    904:                host_frametime = sv_maxtic.value;
                    905:        old_time = realtime;
                    906: 
                    907:        pr_global_struct->frametime = host_frametime;
                    908: 
                    909:        SV_ProgStartFrame ();
                    910: 
                    911: //
                    912: // treat each object in turn
                    913: // even the world gets a chance to think
                    914: //
                    915:        ent = sv.edicts;
                    916:        for (i=0 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
                    917:        {
                    918:                if (ent->free)
                    919:                        continue;
                    920: 
                    921:                if (pr_global_struct->force_retouch)
                    922:                        SV_LinkEdict (ent, true);       // force retouch even for stationary
                    923: 
                    924:                if (i > 0 && i <= MAX_CLIENTS)
                    925:                        continue;               // clients are run directly from packets
                    926: 
                    927:                SV_RunEntity (ent);
                    928:                SV_RunNewmis ();
                    929:        }
                    930:        
                    931:        if (pr_global_struct->force_retouch)
                    932:                pr_global_struct->force_retouch--;      
                    933: }
                    934: 
                    935: void SV_SetMoveVars(void)
                    936: {
                    937:        movevars.gravity                        = sv_gravity.value; 
                    938:        movevars.stopspeed                  = sv_stopspeed.value;                
                    939:        movevars.maxspeed                       = sv_maxspeed.value;                     
                    940:        movevars.spectatormaxspeed  = sv_spectatormaxspeed.value; 
                    941:        movevars.accelerate                 = sv_accelerate.value;               
                    942:        movevars.airaccelerate      = sv_airaccelerate.value;    
                    943:        movevars.wateraccelerate        = sv_wateraccelerate.value;        
                    944:        movevars.friction                       = sv_friction.value;                     
                    945:        movevars.waterfriction      = sv_waterfriction.value;    
                    946:        movevars.entgravity                     = 1.0;
                    947: }

unix.superglobalmegacorp.com

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