#include "cg_local.h"#include "../namespace_begin.h"#include "../namespace_end.h"Go to the source code of this file.
Functions | |
| void | CG_BuildSolidList (void) |
| void | BG_VehicleAdjustBBoxForOrientation (Vehicle_t *veh, vec3_t origin, vec3_t mins, vec3_t maxs, int clientNum, int tracemask, void(*localTrace)(trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentMask)) |
| void | CG_Trace (trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask) |
| void | CG_G2Trace (trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int skipNumber, int mask) |
| int | CG_PointContents (const vec3_t point, int passEntityNum) |
| void | CG_PmoveClientPointerUpdate () |
| qboolean | CG_UsingEWeb (void) |
| void | CG_Cube (vec3_t mins, vec3_t maxs, vec3_t color, float alpha) |
| void | CG_PredictPlayerState (void) |
Variables | |
| playerState_t | cgSendPSPool [MAX_GENTITIES] |
| playerState_t * | cgSendPS [MAX_GENTITIES] |
| vmCvar_t | cg_showVehBounds |
| pmove_t | cg_vehPmove |
| qboolean | cg_vehPmoveSet = qfalse |
|
||||||||||||||||||||||||||||||||
|
Definition at line 9990 of file bg_pmove.c. References trace_t::allsolid, AnglesToAxis(), DEFAULT_MINS_2, vehicleInfo_t::height, vehicleInfo_t::length, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_vOrientation, trace_t::startsolid, vehicleInfo_t::type, vec3_t, VectorCopy, VectorMA, VectorSet, VectorSubtract, Vehicle_t, VH_FIGHTER, VH_FLIER, and vehicleInfo_t::width. Referenced by PmoveSingle().
09993 {
09994 if ( !veh
09995 || !veh->m_pVehicleInfo->length
09996 || !veh->m_pVehicleInfo->width
09997 || !veh->m_pVehicleInfo->height )
09998 //|| veh->m_LandTrace.fraction < 1.0f )
09999 {
10000 return;
10001 }
10002 else if ( veh->m_pVehicleInfo->type != VH_FIGHTER
10003 //&& veh->m_pVehicleInfo->type != VH_SPEEDER
10004 && veh->m_pVehicleInfo->type != VH_FLIER )
10005 {//only those types of vehicles have dynamic bboxes, the rest just use a static bbox
10006 VectorSet( maxs, veh->m_pVehicleInfo->width/2.0f, veh->m_pVehicleInfo->width/2.0f, veh->m_pVehicleInfo->height+DEFAULT_MINS_2 );
10007 VectorSet( mins, veh->m_pVehicleInfo->width/-2.0f, veh->m_pVehicleInfo->width/-2.0f, DEFAULT_MINS_2 );
10008 return;
10009 }
10010 else
10011 {
10012 vec3_t axis[3], point[8];
10013 vec3_t newMins, newMaxs;
10014 int curAxis = 0, i;
10015 trace_t trace;
10016
10017 AnglesToAxis( veh->m_vOrientation, axis );
10018 VectorMA( origin, veh->m_pVehicleInfo->length/2.0f, axis[0], point[0] );
10019 VectorMA( origin, -veh->m_pVehicleInfo->length/2.0f, axis[0], point[1] );
10020 //extrapolate each side up and down
10021 VectorMA( point[0], veh->m_pVehicleInfo->height/2.0f, axis[2], point[0] );
10022 VectorMA( point[0], -veh->m_pVehicleInfo->height, axis[2], point[2] );
10023 VectorMA( point[1], veh->m_pVehicleInfo->height/2.0f, axis[2], point[1] );
10024 VectorMA( point[1], -veh->m_pVehicleInfo->height, axis[2], point[3] );
10025
10026 VectorMA( origin, veh->m_pVehicleInfo->width/2.0f, axis[1], point[4] );
10027 VectorMA( origin, -veh->m_pVehicleInfo->width/2.0f, axis[1], point[5] );
10028 //extrapolate each side up and down
10029 VectorMA( point[4], veh->m_pVehicleInfo->height/2.0f, axis[2], point[4] );
10030 VectorMA( point[4], -veh->m_pVehicleInfo->height, axis[2], point[6] );
10031 VectorMA( point[5], veh->m_pVehicleInfo->height/2.0f, axis[2], point[5] );
10032 VectorMA( point[5], -veh->m_pVehicleInfo->height, axis[2], point[7] );
10033 /*
10034 VectorMA( origin, veh->m_pVehicleInfo->height/2.0f, axis[2], point[4] );
10035 VectorMA( origin, -veh->m_pVehicleInfo->height/2.0f, axis[2], point[5] );
10036 */
10037 //Now inflate a bbox around these points
10038 VectorCopy( origin, newMins );
10039 VectorCopy( origin, newMaxs );
10040 for ( curAxis = 0; curAxis < 3; curAxis++ )
10041 {
10042 for ( i = 0; i < 8; i++ )
10043 {
10044 if ( point[i][curAxis] > newMaxs[curAxis] )
10045 {
10046 newMaxs[curAxis] = point[i][curAxis];
10047 }
10048 else if ( point[i][curAxis] < newMins[curAxis] )
10049 {
10050 newMins[curAxis] = point[i][curAxis];
10051 }
10052 }
10053 }
10054 VectorSubtract( newMins, origin, newMins );
10055 VectorSubtract( newMaxs, origin, newMaxs );
10056 //now see if that's a valid way to be
10057 if (localTrace)
10058 {
10059 localTrace( &trace, origin, newMins, newMaxs, origin, clientNum, tracemask );
10060 }
10061 else
10062 { //don't care about solid stuff then
10063 trace.startsolid = trace.allsolid = 0;
10064 }
10065 if ( !trace.startsolid && !trace.allsolid )
10066 {//let's use it!
10067 VectorCopy( newMins, mins );
10068 VectorCopy( newMaxs, maxs );
10069 }
10070 //else: just use the last one, I guess...?
10071 //FIXME: make it as close as possible? Or actually prevent the change in m_vOrientation? Or push away from anything we hit?
10072 }
10073 }
|
|
|
Definition at line 46 of file cg_predict.c. References centity_t, cg, cg_entities, cg_numpermanents, cg_permanents, playerState_s::clientNum, centity_s::currentState, centity_s::currentValid, DEFAULT_MAXS_2, DEFAULT_MINS_2, snapshot_t::entities, entityState_t, ET_ITEM, ET_PUSH_TRIGGER, ET_TELEPORT_TRIGGER, ET_TERRAIN, entityState_s::eType, centity_s::lerpOrigin, MAX_ENTITIES_IN_SNAPSHOT, cg_t::nextFrameTeleport, cg_t::nextSnap, centity_s::nextState, entityState_s::number, snapshot_t::numEntities, playerState_s::origin, playerMaxs, playerMins, cg_t::predictedPlayerState, snapshot_t::ps, qfalse, qtrue, cg_t::snap, entityState_s::solid, cg_t::thisFrameTeleport, vec3_t, and VectorSubtract. Referenced by CG_SetInitialSnapshot().
00046 {
00047 int i;
00048 centity_t *cent;
00049 snapshot_t *snap;
00050 entityState_t *ent;
00051 vec3_t difference;
00052 float dsquared;
00053
00054 cg_numSolidEntities = 0;
00055 cg_numTriggerEntities = 0;
00056
00057 if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
00058 snap = cg.nextSnap;
00059 } else {
00060 snap = cg.snap;
00061 }
00062
00063 for ( i = 0 ; i < snap->numEntities ; i++ ) {
00064 cent = &cg_entities[ snap->entities[ i ].number ];
00065 ent = ¢->currentState;
00066
00067 if ( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER ) {
00068 cg_triggerEntities[cg_numTriggerEntities] = cent;
00069 cg_numTriggerEntities++;
00070 continue;
00071 }
00072
00073 if ( cent->nextState.solid ) {
00074 cg_solidEntities[cg_numSolidEntities] = cent;
00075 cg_numSolidEntities++;
00076 continue;
00077 }
00078 }
00079
00080 //rww - Horrible, terrible, awful hack.
00081 //We don't send your client entity from the server,
00082 //so it isn't added into the solid list from the snapshot,
00083 //and in addition, it has no solid data. So we will force
00084 //adding it in based on a hardcoded player bbox size.
00085 //This will cause issues if the player box size is ever
00086 //changed..
00087 if (cg_numSolidEntities < MAX_ENTITIES_IN_SNAPSHOT)
00088 {
00089 vec3_t playerMins = {-15, -15, DEFAULT_MINS_2};
00090 vec3_t playerMaxs = {15, 15, DEFAULT_MAXS_2};
00091 int i, j, k;
00092
00093 i = playerMaxs[0];
00094 if (i<1)
00095 i = 1;
00096 if (i>255)
00097 i = 255;
00098
00099 // z is not symetric
00100 j = (-playerMins[2]);
00101 if (j<1)
00102 j = 1;
00103 if (j>255)
00104 j = 255;
00105
00106 // and z playerMaxs can be negative...
00107 k = (playerMaxs[2]+32);
00108 if (k<1)
00109 k = 1;
00110 if (k>255)
00111 k = 255;
00112
00113 cg_solidEntities[cg_numSolidEntities] = &cg_entities[cg.predictedPlayerState.clientNum];
00114 cg_solidEntities[cg_numSolidEntities]->currentState.solid = (k<<16) | (j<<8) | i;
00115
00116 cg_numSolidEntities++;
00117 }
00118
00119 dsquared = /*RMG_distancecull.value*/5000+500;
00120 dsquared *= dsquared;
00121
00122 for(i=0;i<cg_numpermanents;i++)
00123 {
00124 cent = cg_permanents[i];
00125 VectorSubtract(cent->lerpOrigin, snap->ps.origin, difference);
00126 if (cent->currentState.eType == ET_TERRAIN ||
00127 ((difference[0]*difference[0]) + (difference[1]*difference[1]) + (difference[2]*difference[2])) <= dsquared)
00128 {
00129 cent->currentValid = qtrue;
00130 if ( cent->nextState.solid )
00131 {
00132 cg_solidEntities[cg_numSolidEntities] = cent;
00133 cg_numSolidEntities++;
00134 }
00135 }
00136 else
00137 {
00138 cent->currentValid = qfalse;
00139 }
00140 }
00141 }
|
|
||||||||||||||||||||
|
Definition at line 3744 of file cg_ents.c. References addpolyArgStruct_t, addpolyArgStruct_s::alpha1, addpolyArgStruct_s::alpha2, cg, cgs, cg_t::frametime, addpolyArgStruct_s::killTime, cgs_t::media, memset(), addpolyArgStruct_s::numVerts, addpolyArgStruct_s::p, addpolyArgStruct_s::rgb1, addpolyArgStruct_s::rgb2, addpolyArgStruct_s::rotationDelta, addpolyArgStruct_s::shader, cgMedia_t::solidWhite, trap_FX_AddPoly(), vec3_t, and VectorCopy. Referenced by CG_PredictPlayerState().
03745 {
03746 vec3_t rot={0,0,0};
03747 int vec[3];
03748 int axis, i;
03749 addpolyArgStruct_t apArgs;
03750
03751 memset (&apArgs, 0, sizeof(apArgs));
03752
03753 for ( axis = 0, vec[0] = 0, vec[1] = 1, vec[2] = 2; axis < 3; axis++, vec[0]++, vec[1]++, vec[2]++ )
03754 {
03755 for ( i = 0; i < 3; i++ )
03756 {
03757 if ( vec[i] > 2 )
03758 {
03759 vec[i] = 0;
03760 }
03761 }
03762
03763 apArgs.p[0][vec[1]] = mins[vec[1]];
03764 apArgs.p[0][vec[2]] = mins[vec[2]];
03765
03766 apArgs.p[1][vec[1]] = mins[vec[1]];
03767 apArgs.p[1][vec[2]] = maxs[vec[2]];
03768
03769 apArgs.p[2][vec[1]] = maxs[vec[1]];
03770 apArgs.p[2][vec[2]] = maxs[vec[2]];
03771
03772 apArgs.p[3][vec[1]] = maxs[vec[1]];
03773 apArgs.p[3][vec[2]] = mins[vec[2]];
03774
03775 //- face
03776 apArgs.p[0][vec[0]] = apArgs.p[1][vec[0]] = apArgs.p[2][vec[0]] = apArgs.p[3][vec[0]] = mins[vec[0]];
03777
03778 apArgs.numVerts = 4;
03779 apArgs.alpha1 = apArgs.alpha2 = alpha;
03780 VectorCopy( color, apArgs.rgb1 );
03781 VectorCopy( color, apArgs.rgb2 );
03782 VectorCopy( rot, apArgs.rotationDelta );
03783 apArgs.killTime = cg.frametime;
03784 apArgs.shader = cgs.media.solidWhite;
03785
03786 trap_FX_AddPoly( &apArgs );
03787
03788 //+ face
03789 apArgs.p[0][vec[0]] = apArgs.p[1][vec[0]] = apArgs.p[2][vec[0]] = apArgs.p[3][vec[0]] = maxs[vec[0]];
03790
03791 trap_FX_AddPoly( &apArgs );
03792 }
03793 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 376 of file cg_predict.c. References trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, trace_t::fraction, qtrue, trap_CM_BoxTrace(), and vec3_t. Referenced by CG_CheckThirdPersonAlpha(), and CG_G2MarkEvent().
00377 {
00378 trace_t t;
00379
00380 trap_CM_BoxTrace ( &t, start, end, mins, maxs, 0, mask);
00381 t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
00382 // check all other solid models
00383 CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t, qtrue);
00384
00385 *result = t;
00386 }
|
|
|
Definition at line 884 of file cg_predict.c. References pmove_t::baseEnt, bgEntity_t, centity_t, cg_entities, cgSendPS, cgSendPSPool, pmove_t::entSize, pmove_t::ghoul2, MAX_GENTITIES, memset(), NULL, and centity_s::playerState. Referenced by CG_Init().
00885 {
00886 int i;
00887
00888 memset(&cgSendPSPool[0], 0, sizeof(cgSendPSPool));
00889
00890 for ( i = 0 ; i < MAX_GENTITIES ; i++ )
00891 {
00892 #ifdef _XBOX
00893 cgSendPS[i] = NULL;
00894 #else
00895 cgSendPS[i] = &cgSendPSPool[i];
00896 #endif
00897
00898 // These will be invalid at this point on Xbox
00899 cg_entities[i].playerState = cgSendPS[i];
00900 }
00901
00902 #ifdef _XBOX
00903 for ( i = 0; i < CG_SEND_PS_POOL_SIZE - 1; i++ )
00904 {
00905 cgSendPSPool[i].next = &cgSendPSPool[i+1];
00906 }
00907
00908 // Last .next is already NULL from memset above
00909 cgSendPSFreeList = &cgSendPSPool[0];
00910 #endif
00911
00912 //Set up bg entity data
00913 cg_pmove.baseEnt = (bgEntity_t *)cg_entities;
00914 cg_pmove.entSize = sizeof(centity_t);
00915
00916 cg_pmove.ghoul2 = NULL;
00917 }
|
|
||||||||||||
|
Definition at line 393 of file cg_predict.c. References entityState_s::angles, centity_t, clipHandle_t, centity_s::currentState, entityState_t, entityState_s::modelindex, entityState_s::number, entityState_s::origin, entityState_s::solid, SOLID_BMODEL, trap_CM_InlineModel(), trap_CM_PointContents(), trap_CM_TransformedPointContents(), and vec3_t. Referenced by CG_PredictPlayerState().
00393 {
00394 int i;
00395 entityState_t *ent;
00396 centity_t *cent;
00397 clipHandle_t cmodel;
00398 int contents;
00399
00400 contents = trap_CM_PointContents (point, 0);
00401
00402 for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
00403 cent = cg_solidEntities[ i ];
00404
00405 ent = ¢->currentState;
00406
00407 if ( ent->number == passEntityNum ) {
00408 continue;
00409 }
00410
00411 if (ent->solid != SOLID_BMODEL) { // special value for bmodel
00412 continue;
00413 }
00414
00415 cmodel = trap_CM_InlineModel( ent->modelindex );
00416 if ( !cmodel ) {
00417 continue;
00418 }
00419
00420 contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
00421 }
00422
00423 return contents;
00424 }
|
|
|
Definition at line 963 of file cg_predict.c. References AngleSubtract(), pmove_t::animations, pmove_t::baseEnt, bgAllAnims, bgEntity_t, BUTTON_TALK, usercmd_s::buttons, centity_t, cg, CG_AdjustPositionForMover(), CG_Cube(), cg_entities, cg_errorDecay, cg_nopredict, CG_PointContents(), CG_Printf(), cg_showmiss, cg_showVehBounds, cg_showVehMiss, cg_synchronousClients, CG_Trace(), CG_TransitionPlayerState(), CG_UsingEWeb(), cg_vehPmove, cg_vehPmoveSet, cgs, cgSendPS, cgs_t::clientinfo, entityState_s::clientNum, playerState_s::clientNum, pmove_t::cmd, CMD_BACKUP, playerState_s::commandTime, CONTENTS_BODY, centity_s::currentState, pmove_t::debugLevel, cgs_t::debugMelee, pmove_t::debugMelee, cg_t::demoPlayback, DF_NO_FOOTSTEPS, cgs_t::dmflags, pmove_t::entSize, ET_NPC, ET_PLAYER, entityState_s::eType, cg_t::eventSequence, playerState_s::eventSequence, playerState_s::fd, entityState_s::forceFrame, usercmd_s::forwardmove, pmove_t::g2Bolts_LFoot, pmove_t::g2Bolts_RFoot, cgs_t::gametype, pmove_t::gametype, centity_s::ghoul2, pmove_t::ghoul2, playerState_s::groundEntityNum, cg_t::hyperspace, vmCvar_t::integer, entityState_s::legsAnim, playerState_s::legsAnim, entityState_s::legsFlip, playerState_s::legsFlip, centity_s::lerpAngles, centity_s::lerpOrigin, centity_s::localAnimIndex, Vehicle_s::m_iBoarding, Vehicle_s::m_iRemovedSurfaces, playerState_s::m_iVehicleNum, centity_s::m_pVehicle, Vehicle_s::m_ucmd, Vehicle_s::m_vOrientation, MASK_PLAYERSOLID, MAX_GENTITIES, MAX_PS_EVENTS, pmove_t::maxs, memcpy(), pmove_t::mins, saberInfo_t::model, pmove_t::modelScale, centity_s::modelScale, cg_t::nextFrameTeleport, cg_t::nextSnap, pmove_t::noFootsteps, pmove_t::nonHumanoid, cgs_t::noSpecMove, pmove_t::noSpecMove, NPCDEBUG_RED, NULL, entityState_s::number, saberInfo_t::numBlades, cg_t::oldTime, playerState_s::origin, PERS_TEAM, playerState_s::persistant, cg_t::physicsTime, centity_s::playerState, playerState_t, PM_DEAD, playerState_s::pm_flags, PM_INTERMISSION, playerState_s::pm_type, PM_UpdateViewAngles(), PMF_FOLLOW, Pmove(), pmove_fixed, pmove_t::pmove_fixed, pmove_t::pmove_msec, pmove_msec, pmove_t::pointcontents, cg_t::predictedError, cg_t::predictedErrorTime, cg_t::predictedPlayerState, cg_t::predictedVehicleState, pmove_t::ps, snapshot_t::ps, qboolean, qfalse, qtrue, usercmd_s::rightmove, clientInfo_t::saber, forcedata_s::saberAnimLevel, forcedata_s::saberAnimLevelBase, playerState_s::saberHolstered, playerState_s::saberLockEnemy, playerState_s::saberLockFrame, playerState_s::saberLockTime, entityState_s::saberMove, playerState_s::saberMove, snapshot_t::serverTime, usercmd_s::serverTime, playerState_s::slopeRecalcTime, cg_t::snap, entityState_s::solid, SS_DUAL, SS_STAFF, cgs_t::stepSlideFix, pmove_t::stepSlideFix, TEAM_SPECTATOR, cg_t::thisFrameTeleport, cg_t::time, entityState_s::torsoAnim, playerState_s::torsoAnim, entityState_s::torsoFlip, playerState_s::torsoFlip, pmove_t::trace, pmove_t::tracemask, trap_Cvar_Set(), trap_G2API_AddBolt(), trap_GetCurrentCmdNumber(), trap_GetUserCmd(), usercmd_s::upmove, usercmd_t, cg_t::validPPS, vmCvar_t::value, vec3_t, vectoangles(), VectorAdd, VectorClear, VectorCopy, VectorScale, VectorSubtract, playerState_s::vehBoarding, playerState_s::vehOrientation, playerState_s::vehSurfaces, playerState_s::velocity, playerState_s::viewangles, and snapshot_t::vps. Referenced by CG_DrawActiveFrame().
00963 {
00964 int cmdNum, current, i;
00965 playerState_t oldPlayerState;
00966 playerState_t oldVehicleState;
00967 qboolean moved;
00968 usercmd_t oldestCmd;
00969 usercmd_t latestCmd;
00970 centity_t *pEnt;
00971 clientInfo_t *ci;
00972
00973 cg.hyperspace = qfalse; // will be set if touching a trigger_teleport
00974
00975 // if this is the first frame we must guarantee
00976 // predictedPlayerState is valid even if there is some
00977 // other error condition
00978 if ( !cg.validPPS ) {
00979 cg.validPPS = qtrue;
00980 cg.predictedPlayerState = cg.snap->ps;
00981 if (CG_Piloting(cg.snap->ps.m_iVehicleNum))
00982 {
00983 cg.predictedVehicleState = cg.snap->vps;
00984 }
00985 }
00986
00987 // demo playback just copies the moves
00988 if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ) {
00989 CG_InterpolatePlayerState( qfalse );
00990 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
00991 {
00992 CG_InterpolateVehiclePlayerState(qfalse);
00993 }
00994 return;
00995 }
00996
00997 // non-predicting local movement will grab the latest angles
00998 if ( cg_nopredict.integer || cg_synchronousClients.integer || CG_UsingEWeb() ) {
00999 CG_InterpolatePlayerState( qtrue );
01000 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01001 {
01002 CG_InterpolateVehiclePlayerState(qtrue);
01003 }
01004 return;
01005 }
01006
01007 // prepare for pmove
01008 cg_pmove.ps = &cg.predictedPlayerState;
01009 cg_pmove.trace = CG_Trace;
01010 cg_pmove.pointcontents = CG_PointContents;
01011
01012 pEnt = &cg_entities[cg.predictedPlayerState.clientNum];
01013 //rww - bgghoul2
01014 if (cg_pmove.ghoul2 != pEnt->ghoul2) //only update it if the g2 instance has changed
01015 {
01016 if (cg.snap &&
01017 pEnt->ghoul2 &&
01018 !(cg.snap->ps.pm_flags & PMF_FOLLOW) &&
01019 cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR)
01020 {
01021 cg_pmove.ghoul2 = pEnt->ghoul2;
01022 cg_pmove.g2Bolts_LFoot = trap_G2API_AddBolt(pEnt->ghoul2, 0, "*l_leg_foot");
01023 cg_pmove.g2Bolts_RFoot = trap_G2API_AddBolt(pEnt->ghoul2, 0, "*r_leg_foot");
01024 }
01025 else
01026 {
01027 cg_pmove.ghoul2 = NULL;
01028 }
01029 }
01030
01031 ci = &cgs.clientinfo[cg.predictedPlayerState.clientNum];
01032
01033 //I'll just do this every frame in case the scale changes in realtime (don't need to update the g2 inst for that)
01034 VectorCopy(pEnt->modelScale, cg_pmove.modelScale);
01035 //rww end bgghoul2
01036
01037 if ( cg_pmove.ps->pm_type == PM_DEAD ) {
01038 cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
01039 }
01040 else {
01041 cg_pmove.tracemask = MASK_PLAYERSOLID;
01042 }
01043 if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
01044 cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
01045 }
01046 cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
01047
01048 // save the state before the pmove so we can detect transitions
01049 oldPlayerState = cg.predictedPlayerState;
01050 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01051 {
01052 oldVehicleState = cg.predictedVehicleState;
01053 }
01054
01055 current = trap_GetCurrentCmdNumber();
01056
01057 // if we don't have the commands right after the snapshot, we
01058 // can't accurately predict a current position, so just freeze at
01059 // the last good position we had
01060 cmdNum = current - CMD_BACKUP + 1;
01061 trap_GetUserCmd( cmdNum, &oldestCmd );
01062 if ( oldestCmd.serverTime > cg.snap->ps.commandTime
01063 && oldestCmd.serverTime < cg.time ) { // special check for map_restart
01064 if ( cg_showmiss.integer ) {
01065 CG_Printf ("exceeded PACKET_BACKUP on commands\n");
01066 }
01067 return;
01068 }
01069
01070 // get the latest command so we can know which commands are from previous map_restarts
01071 trap_GetUserCmd( current, &latestCmd );
01072
01073 // get the most recent information we have, even if
01074 // the server time is beyond our current cg.time,
01075 // because predicted player positions are going to
01076 // be ahead of everything else anyway
01077 if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
01078 cg.nextSnap->ps.slopeRecalcTime = cg.predictedPlayerState.slopeRecalcTime; //this is the only value we want to maintain seperately on server/client
01079 cg.predictedPlayerState = cg.nextSnap->ps;
01080 if (CG_Piloting(cg.nextSnap->ps.m_iVehicleNum))
01081 {
01082 cg.predictedVehicleState = cg.nextSnap->vps;
01083 }
01084 cg.physicsTime = cg.nextSnap->serverTime;
01085 } else {
01086 cg.snap->ps.slopeRecalcTime = cg.predictedPlayerState.slopeRecalcTime; //this is the only value we want to maintain seperately on server/client
01087 cg.predictedPlayerState = cg.snap->ps;
01088 if (CG_Piloting(cg.snap->ps.m_iVehicleNum))
01089 {
01090 cg.predictedVehicleState = cg.snap->vps;
01091 }
01092 cg.physicsTime = cg.snap->serverTime;
01093 }
01094
01095 if ( pmove_msec.integer < 8 ) {
01096 trap_Cvar_Set("pmove_msec", "8");
01097 }
01098 else if (pmove_msec.integer > 33) {
01099 trap_Cvar_Set("pmove_msec", "33");
01100 }
01101
01102 cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
01103 cg_pmove.pmove_msec = pmove_msec.integer;
01104
01105 for ( i = 0 ; i < MAX_GENTITIES ; i++ )
01106 {
01107 //Written this way for optimal speed, even though it doesn't look pretty.
01108 //(we don't want to spend the time assigning pointers as it does take
01109 //a small precious fraction of time and adds up in the loop.. so says
01110 //the precision timer!)
01111
01112 if (cg_entities[i].currentState.eType == ET_PLAYER ||
01113 cg_entities[i].currentState.eType == ET_NPC)
01114 {
01115 // Need a new playerState_t on Xbox
01116 #ifdef _XBOX
01117 AllocSendPlayerstate(i);
01118 #endif
01119 VectorCopy( cg_entities[i].currentState.pos.trBase, cgSendPS[i]->origin );
01120 VectorCopy( cg_entities[i].currentState.pos.trDelta, cgSendPS[i]->velocity );
01121 cgSendPS[i]->saberLockFrame = cg_entities[i].currentState.forceFrame;
01122 cgSendPS[i]->legsAnim = cg_entities[i].currentState.legsAnim;
01123 cgSendPS[i]->torsoAnim = cg_entities[i].currentState.torsoAnim;
01124 cgSendPS[i]->legsFlip = cg_entities[i].currentState.legsFlip;
01125 cgSendPS[i]->torsoFlip = cg_entities[i].currentState.torsoFlip;
01126 cgSendPS[i]->clientNum = cg_entities[i].currentState.clientNum;
01127 cgSendPS[i]->saberMove = cg_entities[i].currentState.saberMove;
01128 }
01129 }
01130
01131 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01132 {
01133 cg_entities[cg.predictedPlayerState.clientNum].playerState = &cg.predictedPlayerState;
01134 cg_entities[cg.predictedPlayerState.m_iVehicleNum].playerState = &cg.predictedVehicleState;
01135
01136 //use the player command time, because we are running with the player cmds (this is even the case
01137 //on the server)
01138 cg.predictedVehicleState.commandTime = cg.predictedPlayerState.commandTime;
01139 }
01140
01141 // run cmds
01142 moved = qfalse;
01143 for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
01144 // get the command
01145 trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
01146
01147 if ( cg_pmove.pmove_fixed ) {
01148 PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
01149 }
01150
01151 // don't do anything if the time is before the snapshot player time
01152 if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime )
01153 {
01154 continue;
01155 }
01156
01157 // don't do anything if the command was from a previous map_restart
01158 if ( cg_pmove.cmd.serverTime > latestCmd.serverTime ) {
01159 continue;
01160 }
01161
01162 // check for a prediction error from last frame
01163 // on a lan, this will often be the exact value
01164 // from the snapshot, but on a wan we will have
01165 // to predict several commands to get to the point
01166 // we want to compare
01167 if ( CG_Piloting(oldPlayerState.m_iVehicleNum) &&
01168 cg.predictedVehicleState.commandTime == oldVehicleState.commandTime )
01169 {
01170 vec3_t delta;
01171 float len;
01172
01173 if ( cg.thisFrameTeleport ) {
01174 // a teleport will not cause an error decay
01175 VectorClear( cg.predictedError );
01176 if ( cg_showVehMiss.integer ) {
01177 CG_Printf( "VEH PredictionTeleport\n" );
01178 }
01179 cg.thisFrameTeleport = qfalse;
01180 } else {
01181 vec3_t adjusted;
01182 CG_AdjustPositionForMover( cg.predictedVehicleState.origin,
01183 cg.predictedVehicleState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
01184
01185 if ( cg_showVehMiss.integer ) {
01186 if (!VectorCompare( oldVehicleState.origin, adjusted )) {
01187 CG_Printf("VEH prediction error\n");
01188 }
01189 }
01190 VectorSubtract( oldVehicleState.origin, adjusted, delta );
01191 len = VectorLength( delta );
01192 if ( len > 0.1 ) {
01193 if ( cg_showVehMiss.integer ) {
01194 CG_Printf("VEH Prediction miss: %f\n", len);
01195 }
01196 if ( cg_errorDecay.integer ) {
01197 int t;
01198 float f;
01199
01200 t = cg.time - cg.predictedErrorTime;
01201 f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
01202 if ( f < 0 ) {
01203 f = 0;
01204 }
01205 if ( f > 0 && cg_showVehMiss.integer ) {
01206 CG_Printf("VEH Double prediction decay: %f\n", f);
01207 }
01208 VectorScale( cg.predictedError, f, cg.predictedError );
01209 } else {
01210 VectorClear( cg.predictedError );
01211 }
01212 VectorAdd( delta, cg.predictedError, cg.predictedError );
01213 cg.predictedErrorTime = cg.oldTime;
01214 }
01215 //
01216 if ( cg_showVehMiss.integer ) {
01217 if (!VectorCompare( oldVehicleState.vehOrientation, cg.predictedVehicleState.vehOrientation )) {
01218 CG_Printf("VEH orient prediction error\n");
01219 CG_Printf("VEH pitch prediction miss: %f\n", AngleSubtract( oldVehicleState.vehOrientation[0], cg.predictedVehicleState.vehOrientation[0] ) );
01220 CG_Printf("VEH yaw prediction miss: %f\n", AngleSubtract( oldVehicleState.vehOrientation[1], cg.predictedVehicleState.vehOrientation[1] ) );
01221 CG_Printf("VEH roll prediction miss: %f\n", AngleSubtract( oldVehicleState.vehOrientation[2], cg.predictedVehicleState.vehOrientation[2] ) );
01222 }
01223 }
01224 }
01225 }
01226 else if ( !oldPlayerState.m_iVehicleNum && //don't do pred err on ps while riding veh
01227 cg.predictedPlayerState.commandTime == oldPlayerState.commandTime )
01228 {
01229 vec3_t delta;
01230 float len;
01231
01232 if ( cg.thisFrameTeleport ) {
01233 // a teleport will not cause an error decay
01234 VectorClear( cg.predictedError );
01235 if ( cg_showmiss.integer ) {
01236 CG_Printf( "PredictionTeleport\n" );
01237 }
01238 cg.thisFrameTeleport = qfalse;
01239 } else {
01240 vec3_t adjusted;
01241 CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
01242 cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
01243
01244 if ( cg_showmiss.integer ) {
01245 if (!VectorCompare( oldPlayerState.origin, adjusted )) {
01246 CG_Printf("prediction error\n");
01247 }
01248 }
01249 VectorSubtract( oldPlayerState.origin, adjusted, delta );
01250 len = VectorLength( delta );
01251 if ( len > 0.1 ) {
01252 if ( cg_showmiss.integer ) {
01253 CG_Printf("Prediction miss: %f\n", len);
01254 }
01255 if ( cg_errorDecay.integer ) {
01256 int t;
01257 float f;
01258
01259 t = cg.time - cg.predictedErrorTime;
01260 f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
01261 if ( f < 0 ) {
01262 f = 0;
01263 }
01264 if ( f > 0 && cg_showmiss.integer ) {
01265 CG_Printf("Double prediction decay: %f\n", f);
01266 }
01267 VectorScale( cg.predictedError, f, cg.predictedError );
01268 } else {
01269 VectorClear( cg.predictedError );
01270 }
01271 VectorAdd( delta, cg.predictedError, cg.predictedError );
01272 cg.predictedErrorTime = cg.oldTime;
01273 }
01274 }
01275 }
01276
01277 if ( cg_pmove.pmove_fixed ) {
01278 cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
01279 }
01280
01281 cg_pmove.animations = bgAllAnims[pEnt->localAnimIndex].anims;
01282 cg_pmove.gametype = cgs.gametype;
01283
01284 cg_pmove.debugMelee = cgs.debugMelee;
01285 cg_pmove.stepSlideFix = cgs.stepSlideFix;
01286 cg_pmove.noSpecMove = cgs.noSpecMove;
01287
01288 cg_pmove.nonHumanoid = (pEnt->localAnimIndex > 0);
01289
01290 if (cg.snap && cg.snap->ps.saberLockTime > cg.time)
01291 {
01292 centity_t *blockOpp = &cg_entities[cg.snap->ps.saberLockEnemy];
01293
01294 if (blockOpp)
01295 {
01296 vec3_t lockDir, lockAng;
01297
01298 VectorSubtract( blockOpp->lerpOrigin, cg.snap->ps.origin, lockDir );
01299 vectoangles(lockDir, lockAng);
01300
01301 VectorCopy(lockAng, cg_pmove.ps->viewangles);
01302 }
01303 }
01304
01305 //THIS is pretty much bad, but...
01306 cg_pmove.ps->fd.saberAnimLevelBase = cg_pmove.ps->fd.saberAnimLevel;
01307 if ( cg_pmove.ps->saberHolstered == 1 )
01308 {
01309 if ( ci->saber[0].numBlades > 0 )
01310 {
01311 cg_pmove.ps->fd.saberAnimLevelBase = SS_STAFF;
01312 }
01313 else if ( ci->saber[1].model[0] )
01314 {
01315 cg_pmove.ps->fd.saberAnimLevelBase = SS_DUAL;
01316 }
01317 }
01318
01319 Pmove (&cg_pmove);
01320
01321 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum) &&
01322 cg.predictedPlayerState.pm_type != PM_INTERMISSION)
01323 { //we're riding a vehicle, let's predict it
01324 centity_t *veh = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
01325 int x, zd, zu;
01326
01327 if (veh->m_pVehicle)
01328 { //make sure pointer is set up to go to our predicted state
01329 veh->m_pVehicle->m_vOrientation = &cg.predictedVehicleState.vehOrientation[0];
01330
01331 //keep this updated based on what the playerstate says
01332 veh->m_pVehicle->m_iRemovedSurfaces = cg.predictedVehicleState.vehSurfaces;
01333
01334 trap_GetUserCmd( cmdNum, &veh->m_pVehicle->m_ucmd );
01335
01336 if ( veh->m_pVehicle->m_ucmd.buttons & BUTTON_TALK )
01337 { //forced input if "chat bubble" is up
01338 veh->m_pVehicle->m_ucmd.buttons = BUTTON_TALK;
01339 veh->m_pVehicle->m_ucmd.forwardmove = 0;
01340 veh->m_pVehicle->m_ucmd.rightmove = 0;
01341 veh->m_pVehicle->m_ucmd.upmove = 0;
01342 }
01343 cg_vehPmove.ps = &cg.predictedVehicleState;
01344 cg_vehPmove.animations = bgAllAnims[veh->localAnimIndex].anims;
01345
01346 memcpy(&cg_vehPmove.cmd, &veh->m_pVehicle->m_ucmd, sizeof(usercmd_t));
01347 /*
01348 cg_vehPmove.cmd.rightmove = 0; //no vehicle can move right/left
01349 cg_vehPmove.cmd.upmove = 0; //no vehicle can move up/down
01350 */
01351
01352 cg_vehPmove.gametype = cgs.gametype;
01353 cg_vehPmove.ghoul2 = veh->ghoul2;
01354
01355 cg_vehPmove.nonHumanoid = (veh->localAnimIndex > 0);
01356
01357 /*
01358 x = (veh->currentState.solid & 255);
01359 zd = (veh->currentState.solid & 255);
01360 zu = (veh->currentState.solid & 255) - 32;
01361
01362 cg_vehPmove.mins[0] = cg_vehPmove.mins[1] = -x;
01363 cg_vehPmove.maxs[0] = cg_vehPmove.maxs[1] = x;
01364 cg_vehPmove.mins[2] = -zd;
01365 cg_vehPmove.maxs[2] = zu;
01366 */
01367 //I think this was actually wrong.. just copy-pasted from id code. Oh well.
01368 x = (veh->currentState.solid)&255;
01369 zd = (veh->currentState.solid>>8)&255;
01370 zu = (veh->currentState.solid>>15)&255;
01371
01372 zu -= 32; //I don't quite get the reason for this.
01373 zd = -zd;
01374
01375 //z/y must be symmetrical (blah)
01376 cg_vehPmove.mins[0] = cg_vehPmove.mins[1] = -x;
01377 cg_vehPmove.maxs[0] = cg_vehPmove.maxs[1] = x;
01378 cg_vehPmove.mins[2] = zd;
01379 cg_vehPmove.maxs[2] = zu;
01380
01381 VectorCopy(veh->modelScale, cg_vehPmove.modelScale);
01382
01383 if (!cg_vehPmoveSet)
01384 { //do all the one-time things
01385 cg_vehPmove.trace = CG_Trace;
01386 cg_vehPmove.pointcontents = CG_PointContents;
01387 cg_vehPmove.tracemask = MASK_PLAYERSOLID;
01388 cg_vehPmove.debugLevel = 0;
01389 cg_vehPmove.g2Bolts_LFoot = -1;
01390 cg_vehPmove.g2Bolts_RFoot = -1;
01391
01392 cg_vehPmove.baseEnt = (bgEntity_t *)cg_entities;
01393 cg_vehPmove.entSize = sizeof(centity_t);
01394
01395 cg_vehPmoveSet = qtrue;
01396 }
01397
01398 cg_vehPmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
01399 cg_vehPmove.pmove_fixed = pmove_fixed.integer;
01400 cg_vehPmove.pmove_msec = pmove_msec.integer;
01401
01402 cg_entities[cg.predictedPlayerState.clientNum].playerState = &cg.predictedPlayerState;
01403 veh->playerState = &cg.predictedVehicleState;
01404
01405 //update boarding value sent from server. boarding is not predicted, but no big deal
01406 veh->m_pVehicle->m_iBoarding = cg.predictedVehicleState.vehBoarding;
01407
01408 Pmove(&cg_vehPmove);
01409 /*
01410 if ( !cg_paused.integer )
01411 {
01412 Com_Printf( "%d - PITCH change %4.2f\n", cg.time, AngleSubtract(veh->m_pVehicle->m_vOrientation[0],veh->m_pVehicle->m_vPrevOrientation[0]) );
01413 }
01414 */
01415 if ( cg_showVehBounds.integer )
01416 {
01417 vec3_t NPCDEBUG_RED = {1.0, 0.0, 0.0};
01418 vec3_t absmin, absmax;
01419 VectorAdd( cg_vehPmove.ps->origin, cg_vehPmove.mins, absmin );
01420 VectorAdd( cg_vehPmove.ps->origin, cg_vehPmove.maxs, absmax );
01421 CG_Cube( absmin, absmax, NPCDEBUG_RED, 0.25 );
01422 }
01423 }
01424 }
01425
01426 moved = qtrue;
01427
01428 // add push trigger movement effects
01429 CG_TouchTriggerPrediction();
01430
01431 // check for predictable events that changed from previous predictions
01432 //CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
01433 }
01434
01435 if ( cg_showmiss.integer > 1 ) {
01436 CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
01437 }
01438
01439 if ( !moved ) {
01440 if ( cg_showmiss.integer ) {
01441 CG_Printf( "not moved\n" );
01442 }
01443 goto revertES;
01444 }
01445
01446 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01447 {
01448 CG_AdjustPositionForMover( cg.predictedVehicleState.origin,
01449 cg.predictedVehicleState.groundEntityNum,
01450 cg.physicsTime, cg.time, cg.predictedVehicleState.origin );
01451 }
01452 else
01453 {
01454 // adjust for the movement of the groundentity
01455 CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
01456 cg.predictedPlayerState.groundEntityNum,
01457 cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
01458 }
01459
01460 if ( cg_showmiss.integer ) {
01461 if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
01462 CG_Printf("WARNING: dropped event\n");
01463 }
01464 }
01465
01466 // fire events and other transition triggered things
01467 CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
01468
01469 if ( cg_showmiss.integer ) {
01470 if (cg.eventSequence > cg.predictedPlayerState.eventSequence) {
01471 CG_Printf("WARNING: double event\n");
01472 cg.eventSequence = cg.predictedPlayerState.eventSequence;
01473 }
01474 }
01475
01476 if (cg.predictedPlayerState.m_iVehicleNum &&
01477 !CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01478 { //a passenger on this vehicle, bolt them in
01479 centity_t *veh = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
01480 VectorCopy(veh->lerpAngles, cg.predictedPlayerState.viewangles);
01481 VectorCopy(veh->lerpOrigin, cg.predictedPlayerState.origin);
01482 }
01483
01484 revertES:
01485 if (CG_Piloting(cg.predictedPlayerState.m_iVehicleNum))
01486 {
01487 centity_t *veh = &cg_entities[cg.predictedPlayerState.m_iVehicleNum];
01488
01489 if (veh->m_pVehicle)
01490 {
01491 //switch ptr back for this ent in case we stop riding it
01492 veh->m_pVehicle->m_vOrientation = &cgSendPS[veh->currentState.number]->vehOrientation[0];
01493 }
01494
01495 cg_entities[cg.predictedPlayerState.clientNum].playerState = cgSendPS[cg.predictedPlayerState.clientNum];
01496 veh->playerState = cgSendPS[veh->currentState.number];
01497 }
01498
01499 //copy some stuff back into the entstates to help actually "predict" them if applicable
01500 for ( i = 0 ; i < MAX_GENTITIES ; i++ )
01501 {
01502 if (cg_entities[i].currentState.eType == ET_PLAYER ||
01503 cg_entities[i].currentState.eType == ET_NPC)
01504 {
01505 cg_entities[i].currentState.torsoAnim = cgSendPS[i]->torsoAnim;
01506 cg_entities[i].currentState.legsAnim = cgSendPS[i]->legsAnim;
01507 cg_entities[i].currentState.forceFrame = cgSendPS[i]->saberLockFrame;
01508 cg_entities[i].currentState.saberMove = cgSendPS[i]->saberMove;
01509 }
01510 }
01511 }
|
|
||||||||||||||||||||||||||||||||
|
Definition at line 359 of file cg_predict.c. References trace_t::entityNum, ENTITYNUM_NONE, ENTITYNUM_WORLD, trace_t::fraction, qfalse, trap_CM_BoxTrace(), and vec3_t. Referenced by CG_AddFragment(), CG_AddSaberBlade(), CG_BracketEntity(), CG_CalcEntityLerpPositions(), CG_DrawAutoMap(), CG_EntityEvent(), CG_G2SaberEffects(), CG_PredictPlayerState(), CG_SaberClashFlare(), CG_SaberCompWork(), and ValidBloodPool().
00360 {
00361 trace_t t;
00362
00363 trap_CM_BoxTrace ( &t, start, end, mins, maxs, 0, mask);
00364 t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
00365 // check all other solid models
00366 CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t, qfalse);
00367
00368 *result = t;
00369 }
|
|
|
Definition at line 920 of file cg_predict.c. References cg, cg_entities, playerState_s::emplacedIndex, cg_t::predictedPlayerState, qboolean, qfalse, qtrue, playerState_s::weapon, WP_EMPLACED_GUN, and WP_NONE. Referenced by CG_PredictPlayerState().
00921 {
00922 if (cg.predictedPlayerState.weapon == WP_EMPLACED_GUN && cg.predictedPlayerState.emplacedIndex &&
00923 cg_entities[cg.predictedPlayerState.emplacedIndex].currentState.weapon == WP_NONE)
00924 {
00925 return qtrue;
00926 }
00927
00928 return qfalse;
00929 }
|
|
|
Definition at line 958 of file cg_predict.c. Referenced by CG_PredictPlayerState(). |
|
|
Definition at line 959 of file cg_predict.c. Referenced by CG_PredictPlayerState(). |
|
|
Definition at line 960 of file cg_predict.c. Referenced by CG_PredictPlayerState(). |
|
|
Definition at line 856 of file cg_predict.c. |
|
|
Definition at line 853 of file cg_predict.c. Referenced by CG_PmoveClientPointerUpdate(). |