/* ================= G_TimeShiftClient Move a client back to where he was at the specified "time" ================= */ void G_TimeShiftClient( gentity_t *ent, int time ) { int j, k; if ( time > level.time ) { time = level.time; } // find two entries in the origin trail whose times sandwich "time" // assumes no two adjacent trail records have the same timestamp j = k = ent->client->trailHead; do { if ( ent->client->trail[j].time <= time ) break; k = j; j--; if ( j < 0 ) { j = NUM_CLIENT_TRAILS - 1; } } while ( j != ent->client->trailHead ); // if we got past the first iteration above, we've sandwiched (or wrapped) if ( j != k ) { // make sure it doesn't get re-saved if ( ent->client->saved.leveltime != level.time ) { // save the current origin and bounding box VectorCopy( &ent->r.mins, &ent->client->saved.mins ); VectorCopy( &ent->r.maxs, &ent->client->saved.maxs ); VectorCopy( &ent->r.currentOrigin, &ent->client->saved.currentOrigin ); VectorCopy( &ent->r.currentAngles, &ent->client->saved.currentAngles ); ent->client->saved.leveltime = level.time; } // if we haven't wrapped back to the head, we've sandwiched, so // we shift the client's position back to where he was at "time" if ( j != ent->client->trailHead ) { float frac = (float)(ent->client->trail[k].time - time) / (float)(ent->client->trail[k].time - ent->client->trail[j].time); // FOR TESTING ONLY // Com_Printf( "level time: %d, fire time: %d, j time: %d, k time: %d\n", level.time, time, ent->client->trail[j].time, ent->client->trail[k].time ); // interpolate between the two origins to give position at time index "time" TimeShiftLerp( frac, &ent->client->trail[k].currentOrigin, &ent->client->trail[j].currentOrigin, &ent->r.currentOrigin ); ent->r.currentAngles.yaw = LerpAngle( ent->client->trail[k].currentAngles.yaw, ent->r.currentAngles.yaw, frac ); // lerp these too, just for fun (and ducking) TimeShiftLerp( frac, &ent->client->trail[k].mins, &ent->client->trail[j].mins, &ent->r.mins ); TimeShiftLerp( frac, &ent->client->trail[k].maxs, &ent->client->trail[j].maxs, &ent->r.maxs ); // this will recalculate absmin and absmax trap->LinkEntity( (sharedEntity_t *)ent ); } else { // we wrapped, so grab the earliest VectorCopy( &ent->client->trail[k].currentAngles, &ent->r.currentAngles ); VectorCopy( &ent->client->trail[k].currentOrigin, &ent->r.currentOrigin ); VectorCopy( &ent->client->trail[k].mins, &ent->r.mins ); VectorCopy( &ent->client->trail[k].maxs, &ent->r.maxs ); // this will recalculate absmin and absmax trap->LinkEntity( (sharedEntity_t *)ent ); } } }
/** * @brief G_AdjustSingleClientPosition * @param[in,out] ent * @param[in] time */ static void G_AdjustSingleClientPosition(gentity_t *ent, int time) { int i, j; if (time > level.time) { time = level.time; } // no lerping forward.... if (!G_AntilagSafe(ent)) { return; } // find a pair of markers which bound the requested time i = j = ent->client->topMarker; do { if (ent->client->clientMarkers[i].time <= time) { break; } j = i; i--; if (i < 0) { i = MAX_CLIENT_MARKERS - 1; } } while (i != ent->client->topMarker); if (i == j) // oops, no valid stored markers { return; } // save current position to backup if (ent->client->backupMarker.time != level.time) { VectorCopy(ent->r.currentOrigin, ent->client->backupMarker.origin); VectorCopy(ent->r.mins, ent->client->backupMarker.mins); VectorCopy(ent->r.maxs, ent->client->backupMarker.maxs); // Head, Legs VectorCopy(ent->client->ps.viewangles, ent->client->backupMarker.viewangles); ent->client->backupMarker.eFlags = ent->client->ps.eFlags; ent->client->backupMarker.pm_flags = ent->client->ps.pm_flags; ent->client->backupMarker.viewheight = ent->client->ps.viewheight; ent->client->backupMarker.time = level.time; // Torso Markers ent->client->backupMarker.torsoOldFrameModel = ent->torsoFrame.oldFrameModel; ent->client->backupMarker.torsoFrameModel = ent->torsoFrame.frameModel; ent->client->backupMarker.torsoOldFrame = ent->torsoFrame.oldFrame; ent->client->backupMarker.torsoFrame = ent->torsoFrame.frame; ent->client->backupMarker.torsoOldFrameTime = ent->torsoFrame.oldFrameTime; ent->client->backupMarker.torsoFrameTime = ent->torsoFrame.frameTime; ent->client->backupMarker.torsoYawAngle = ent->torsoFrame.yawAngle; ent->client->backupMarker.torsoPitchAngle = ent->torsoFrame.pitchAngle; ent->client->backupMarker.torsoYawing = ent->torsoFrame.yawing; ent->client->backupMarker.torsoPitching = ent->torsoFrame.pitching; // Legs Markers ent->client->backupMarker.legsOldFrameModel = ent->legsFrame.oldFrameModel; ent->client->backupMarker.legsFrameModel = ent->legsFrame.frameModel; ent->client->backupMarker.legsOldFrame = ent->legsFrame.oldFrame; ent->client->backupMarker.legsFrame = ent->legsFrame.frame; ent->client->backupMarker.legsOldFrameTime = ent->legsFrame.oldFrameTime; ent->client->backupMarker.legsFrameTime = ent->legsFrame.frameTime; ent->client->backupMarker.legsYawAngle = ent->legsFrame.yawAngle; ent->client->backupMarker.legsPitchAngle = ent->legsFrame.pitchAngle; ent->client->backupMarker.legsYawing = ent->legsFrame.yawing; ent->client->backupMarker.legsPitching = ent->legsFrame.pitching; } if (i != ent->client->topMarker) { float frac = (float)(time - ent->client->clientMarkers[i].time) / (float)(ent->client->clientMarkers[j].time - ent->client->clientMarkers[i].time); //LerpPosition(ent->client->clientMarkers[i].origin, ent->client->clientMarkers[j].origin, frac, ent->r.currentOrigin); //LerpPosition(ent->client->clientMarkers[i].mins, ent->client->clientMarkers[j].mins, frac, ent->r.mins); //LerpPosition(ent->client->clientMarkers[i].maxs, ent->client->clientMarkers[j].maxs, frac, ent->r.maxs); // Using TimeShiftLerp since it follows the client exactly meaning less roundoff error TimeShiftLerp( ent->client->clientMarkers[i].origin, ent->client->clientMarkers[j].origin, frac, ent->r.currentOrigin); TimeShiftLerp( ent->client->clientMarkers[i].mins, ent->client->clientMarkers[j].mins, frac, ent->r.mins); TimeShiftLerp( ent->client->clientMarkers[i].maxs, ent->client->clientMarkers[j].maxs, frac, ent->r.maxs); // These are for Head / Legs ent->client->ps.viewangles[0] = LerpAngle( ent->client->clientMarkers[i].viewangles[0], ent->client->clientMarkers[j].viewangles[0], frac); ent->client->ps.viewangles[1] = LerpAngle( ent->client->clientMarkers[i].viewangles[1], ent->client->clientMarkers[j].viewangles[1], frac); ent->client->ps.viewangles[2] = LerpAngle( ent->client->clientMarkers[i].viewangles[2], ent->client->clientMarkers[j].viewangles[2], frac); // Set the ints to the closest ones in time since you can't lerp them. if ((ent->client->clientMarkers[j].time - time) < (time - ent->client->clientMarkers[i].time)) { ent->client->ps.eFlags = ent->client->clientMarkers[j].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[j].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[j].viewheight; // Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[j].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[j].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[j].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[j].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[j].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[j].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[j].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[j].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[j].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[j].torsoPitching; // Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[j].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[j].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[j].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[j].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[j].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[j].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[j].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[j].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[j].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[j].legsPitching; // time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[j].time; } else { ent->client->ps.eFlags = ent->client->clientMarkers[i].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[i].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[i].viewheight; // Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[i].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[i].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[i].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[i].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[i].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[i].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[i].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[i].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[i].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[i].torsoPitching; // Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[i].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[i].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[i].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[i].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[i].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[i].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[i].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[i].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[i].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[i].legsPitching; // time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[i].time; } /* FIXME if ( debugger && debugger->client) { // print some debugging stuff exactly like what the client does // it starts with "Rec:" to let you know it backward-reconciled char msg[2048]; Com_sprintf( msg, sizeof(msg), "print \"^1Rec: time: %d, j: %d, k: %d, origin: %0.2f %0.2f %0.2f\n" "^2frac: %0.4f, origin1: %0.2f %0.2f %0.2f, origin2: %0.2f %0.2f %0.2f\n" "^7level.time: %d, est time: %d, level.time delta: %d, est real ping: %d\n\"", time, ent->client->clientMarkers[i].time, ent->client->clientMarkers[j].time, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], frac, ent->client->clientMarkers[i].origin[0], ent->client->clientMarkers[i].origin[1], ent->client->clientMarkers[i].origin[2], ent->client->clientMarkers[j].origin[0], ent->client->clientMarkers[j].origin[1], ent->client->clientMarkers[j].origin[2], level.time, level.time + debugger->client->frameOffset, level.time - time, level.time + debugger->client->frameOffset - time); trap_SendServerCommand( debugger - g_entities, msg ); } */ } else { VectorCopy(ent->client->clientMarkers[j].origin, ent->r.currentOrigin); VectorCopy(ent->client->clientMarkers[j].mins, ent->r.mins); VectorCopy(ent->client->clientMarkers[j].maxs, ent->r.maxs); // BuildHead/Legs uses these VectorCopy(ent->client->clientMarkers[j].viewangles, ent->client->ps.viewangles); ent->client->ps.eFlags = ent->client->clientMarkers[j].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[j].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[j].viewheight; // Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[j].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[j].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[j].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[j].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[j].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[j].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[j].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[j].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[j].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[j].torsoPitching; // Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[j].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[j].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[j].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[j].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[j].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[j].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[j].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[j].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[j].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[j].legsPitching; // time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[j].time; } trap_LinkEntity(ent); }
/* ================= G_TimeShiftClient Move a client back to where he was at the specified "time" ================= */ void G_TimeShiftClient( gentity_t *ent, int time, qboolean debug, gentity_t *debugger ) { int j, k; char msg[2048]; // this will dump out the head index, and the time for all the stored positions /* if ( debug ) { char str[MAX_STRING_CHARS]; Com_sprintf(str, sizeof(str), "print \"head: %d, %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n\"", ent->client->historyHead, ent->client->history[0].leveltime, ent->client->history[1].leveltime, ent->client->history[2].leveltime, ent->client->history[3].leveltime, ent->client->history[4].leveltime, ent->client->history[5].leveltime, ent->client->history[6].leveltime, ent->client->history[7].leveltime, ent->client->history[8].leveltime, ent->client->history[9].leveltime, ent->client->history[10].leveltime, ent->client->history[11].leveltime, ent->client->history[12].leveltime, ent->client->history[13].leveltime, ent->client->history[14].leveltime, ent->client->history[15].leveltime, ent->client->history[16].leveltime); trap_SendServerCommand( debugger - g_entities, str ); } */ // find two entries in the history whose times sandwich "time" // assumes no two adjacent records have the same timestamp j = k = ent->client->historyHead; do { if ( ent->client->history[j].leveltime <= time ) break; k = j; j--; if ( j < 0 ) { j = NUM_CLIENT_HISTORY - 1; } } while ( j != ent->client->historyHead ); // if we got past the first iteration above, we've sandwiched (or wrapped) if ( j != k ) { // make sure it doesn't get re-saved if ( ent->client->saved.leveltime != level.time ) { // save the current origin and bounding box VectorCopy( ent->r.mins, ent->client->saved.mins ); VectorCopy( ent->r.maxs, ent->client->saved.maxs ); VectorCopy( ent->r.currentOrigin, ent->client->saved.currentOrigin ); ent->client->saved.leveltime = level.time; } // if we haven't wrapped back to the head, we've sandwiched, so // we shift the client's position back to where he was at "time" if ( j != ent->client->historyHead ) { float frac = (float)(time - ent->client->history[j].leveltime) / (float)(ent->client->history[k].leveltime - ent->client->history[j].leveltime); // interpolate between the two origins to give position at time index "time" TimeShiftLerp( frac, ent->client->history[j].currentOrigin, ent->client->history[k].currentOrigin, ent->r.currentOrigin ); // lerp these too, just for fun (and ducking) TimeShiftLerp( frac, ent->client->history[j].mins, ent->client->history[k].mins, ent->r.mins ); TimeShiftLerp( frac, ent->client->history[j].maxs, ent->client->history[k].maxs, ent->r.maxs ); if ( debug && debugger != NULL ) { // print some debugging stuff exactly like what the client does // it starts with "Rec:" to let you know it backward-reconciled Com_sprintf( msg, sizeof(msg), "print \"^1Rec: time: %d, j: %d, k: %d, origin: %0.2f %0.2f %0.2f\n" "^2frac: %0.4f, origin1: %0.2f %0.2f %0.2f, origin2: %0.2f %0.2f %0.2f\n" "^7level.time: %d, est time: %d, level.time delta: %d, est real ping: %d\n\"", time, ent->client->history[j].leveltime, ent->client->history[k].leveltime, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], frac, ent->client->history[j].currentOrigin[0], ent->client->history[j].currentOrigin[1], ent->client->history[j].currentOrigin[2], ent->client->history[k].currentOrigin[0], ent->client->history[k].currentOrigin[1], ent->client->history[k].currentOrigin[2], level.time, level.time + debugger->client->frameOffset, level.time - time, level.time + debugger->client->frameOffset - time); trap_SendServerCommand( debugger - g_entities, msg ); } // this will recalculate absmin and absmax trap_LinkEntity( ent ); } else { // we wrapped, so grab the earliest VectorCopy( ent->client->history[k].currentOrigin, ent->r.currentOrigin ); VectorCopy( ent->client->history[k].mins, ent->r.mins ); VectorCopy( ent->client->history[k].maxs, ent->r.maxs ); // this will recalculate absmin and absmax trap_LinkEntity( ent ); } } else { // this only happens when the client is using a negative timenudge, because that // number is added to the command time // print some debugging stuff exactly like what the client does // it starts with "No rec:" to let you know it didn't backward-reconcile if ( debug && debugger != NULL ) { Com_sprintf( msg, sizeof(msg), "print \"^1No rec: time: %d, j: %d, k: %d, origin: %0.2f %0.2f %0.2f\n" "^2frac: %0.4f, origin1: %0.2f %0.2f %0.2f, origin2: %0.2f %0.2f %0.2f\n" "^7level.time: %d, est time: %d, level.time delta: %d, est real ping: %d\n\"", time, level.time, level.time, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], 0.0f, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], level.time, level.time + debugger->client->frameOffset, level.time - time, level.time + debugger->client->frameOffset - time); trap_SendServerCommand( debugger - g_entities, msg ); } } }
void G_AdjustSingleClientPosition( gentity_t* ent, int time, gentity_t* debugger) { int i, j; // unlagged analogies: antilag i = unlagged j, antilag j = unlagged k if( time > level.time ) { time = level.time; } // no lerping forward.... You mean extrapolating, not lerping (inter) if(!G_AntilagSafe(ent)) return; // find a pair of markers which bound the requested time i = j = ent->client->topMarker; do { if( ent->client->clientMarkers[i].time <= time ) { break; } j = i; i--; if( i < 0 ) { i = MAX_CLIENT_MARKERS - 1; } } while( i != ent->client->topMarker ); if( i == j ) { // oops, no valid stored markers return; } // josh: from unlagged make sure it doesn't get backed-up twice if ( ent->client->backupMarker.time != level.time ) { VectorCopy(ent->r.currentOrigin, ent->client->backupMarker.origin); VectorCopy(ent->r.mins, ent->client->backupMarker.mins); VectorCopy(ent->r.maxs, ent->client->backupMarker.maxs); //josh: for Head, Legs VectorCopy(ent->client->ps.viewangles, ent->client->backupMarker.viewangles); ent->client->backupMarker.eFlags = ent->client->ps.eFlags; ent->client->backupMarker.pm_flags = ent->client->ps.pm_flags; ent->client->backupMarker.viewheight = ent->client->ps.viewheight; // josh: This was missing, but needed or else no readjustment ent->client->backupMarker.time = level.time; // forty - realistic hitboxes - Torso Markers ent->client->backupMarker.torsoOldFrameModel = ent->torsoFrame.oldFrameModel; ent->client->backupMarker.torsoFrameModel = ent->torsoFrame.frameModel; ent->client->backupMarker.torsoOldFrame = ent->torsoFrame.oldFrame; ent->client->backupMarker.torsoFrame = ent->torsoFrame.frame; ent->client->backupMarker.torsoOldFrameTime = ent->torsoFrame.oldFrameTime; ent->client->backupMarker.torsoFrameTime = ent->torsoFrame.frameTime; ent->client->backupMarker.torsoYawAngle = ent->torsoFrame.yawAngle; ent->client->backupMarker.torsoPitchAngle = ent->torsoFrame.pitchAngle; ent->client->backupMarker.torsoYawing = ent->torsoFrame.yawing; ent->client->backupMarker.torsoPitching = ent->torsoFrame.pitching; // forty - realistic hitboxes - Legs Markers ent->client->backupMarker.legsOldFrameModel = ent->legsFrame.oldFrameModel; ent->client->backupMarker.legsFrameModel = ent->legsFrame.frameModel; ent->client->backupMarker.legsOldFrame = ent->legsFrame.oldFrame; ent->client->backupMarker.legsFrame = ent->legsFrame.frame; ent->client->backupMarker.legsOldFrameTime = ent->legsFrame.oldFrameTime; ent->client->backupMarker.legsFrameTime = ent->legsFrame.frameTime; ent->client->backupMarker.legsYawAngle = ent->legsFrame.yawAngle; ent->client->backupMarker.legsPitchAngle = ent->legsFrame.pitchAngle; ent->client->backupMarker.legsYawing = ent->legsFrame.yawing; ent->client->backupMarker.legsPitching = ent->legsFrame.pitching; } if(i != ent->client->topMarker) { //float frac = ((float)(ent->client->clientMarkers[j].time - time)) / (ent->client->clientMarkers[j].time - ent->client->clientMarkers[i].time); //josh: reversing the order to better match the client and prevent //roundoff error float frac = (float)(time - ent->client->clientMarkers[i].time) / (float)(ent->client->clientMarkers[j].time - ent->client->clientMarkers[i].time); //LerpPosition(ent->client->clientMarkers[i].origin, ent->client->clientMarkers[j].origin, frac, ent->r.currentOrigin); //LerpPosition(ent->client->clientMarkers[i].mins, ent->client->clientMarkers[j].mins, frac, ent->r.mins); //LerpPosition(ent->client->clientMarkers[i].maxs, ent->client->clientMarkers[j].maxs, frac, ent->r.maxs); //josh: Using TimeShiftLerp since it follows the client exactly //meaning less roundoff error TimeShiftLerp( ent->client->clientMarkers[i].origin, ent->client->clientMarkers[j].origin, frac, ent->r.currentOrigin); TimeShiftLerp( ent->client->clientMarkers[i].mins, ent->client->clientMarkers[j].mins, frac, ent->r.mins); TimeShiftLerp( ent->client->clientMarkers[i].maxs, ent->client->clientMarkers[j].maxs, frac, ent->r.maxs); // These are for Head / Legs ent->client->ps.viewangles[0] = LerpAngle( ent->client->clientMarkers[i].viewangles[0], ent->client->clientMarkers[j].viewangles[0], frac); ent->client->ps.viewangles[1] = LerpAngle( ent->client->clientMarkers[i].viewangles[1], ent->client->clientMarkers[j].viewangles[1], frac); ent->client->ps.viewangles[2] = LerpAngle( ent->client->clientMarkers[i].viewangles[2], ent->client->clientMarkers[j].viewangles[2], frac); // josh: Set the ints to the closest ones in time since you can't // lerp them. if((ent->client->clientMarkers[j].time - time) < (time - ent->client->clientMarkers[i].time)) { ent->client->ps.eFlags = ent->client->clientMarkers[j].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[j].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[j].viewheight; // forty - realistic hitboxes - Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[j].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[j].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[j].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[j].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[j].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[j].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[j].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[j].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[j].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[j].torsoPitching; // forty - realistic hitboxes - Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[j].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[j].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[j].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[j].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[j].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[j].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[j].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[j].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[j].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[j].legsPitching; // forty - realistic hitboxes - time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[j].time; } else { ent->client->ps.eFlags = ent->client->clientMarkers[i].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[i].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[i].viewheight; // forty - realistic hitboxes - Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[i].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[i].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[i].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[i].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[i].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[i].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[i].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[i].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[i].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[i].torsoPitching; // forty - realistic hitboxes - Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[i].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[i].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[i].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[i].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[i].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[i].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[i].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[i].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[i].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[i].legsPitching; // forty - realistic hitboxes - time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[i].time; } if ( debugger && debugger->client) { // print some debugging stuff exactly like what the client does // it starts with "Rec:" to let you know it backward-reconciled char msg[2048]; Com_sprintf( msg, sizeof(msg), "print \"^1Rec: time: %d, j: %d, k: %d, origin: %0.2f %0.2f %0.2f\n" "^2frac: %0.4f, origin1: %0.2f %0.2f %0.2f, origin2: %0.2f %0.2f %0.2f\n" "^7level.time: %d, est time: %d, level.time delta: %d, est real ping: %d\n\"", time, ent->client->clientMarkers[i].time, ent->client->clientMarkers[j].time, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2], frac, ent->client->clientMarkers[i].origin[0], ent->client->clientMarkers[i].origin[1], ent->client->clientMarkers[i].origin[2], ent->client->clientMarkers[j].origin[0], ent->client->clientMarkers[j].origin[1], ent->client->clientMarkers[j].origin[2], level.time, level.time + debugger->client->frameOffset, level.time - time, level.time + debugger->client->frameOffset - time); trap_SendServerCommand( debugger - g_entities, msg ); } } else { VectorCopy( ent->client->clientMarkers[j].origin, ent->r.currentOrigin ); VectorCopy( ent->client->clientMarkers[j].mins, ent->r.mins ); VectorCopy( ent->client->clientMarkers[j].maxs, ent->r.maxs ); //// josh: BuildHead/Legs uses these VectorCopy(ent->client->clientMarkers[j].viewangles, ent->client->ps.viewangles); ent->client->ps.eFlags = ent->client->clientMarkers[j].eFlags; ent->client->ps.pm_flags = ent->client->clientMarkers[j].pm_flags; ent->client->ps.viewheight = ent->client->clientMarkers[j].viewheight; // forty - realistic hitboxes - Torso Markers ent->torsoFrame.oldFrameModel = ent->client->clientMarkers[j].torsoOldFrameModel; ent->torsoFrame.frameModel = ent->client->clientMarkers[j].torsoFrameModel; ent->torsoFrame.oldFrame = ent->client->clientMarkers[j].torsoOldFrame; ent->torsoFrame.frame = ent->client->clientMarkers[j].torsoFrame; ent->torsoFrame.oldFrameTime = ent->client->clientMarkers[j].torsoOldFrameTime; ent->torsoFrame.frameTime = ent->client->clientMarkers[j].torsoFrameTime; ent->torsoFrame.yawAngle = ent->client->clientMarkers[j].torsoYawAngle; ent->torsoFrame.pitchAngle = ent->client->clientMarkers[j].torsoPitchAngle; ent->torsoFrame.yawing = ent->client->clientMarkers[j].torsoYawing; ent->torsoFrame.pitching = ent->client->clientMarkers[j].torsoPitching; // forty - realistic hitboxes - Legs Markers ent->legsFrame.oldFrameModel = ent->client->clientMarkers[j].legsOldFrameModel; ent->legsFrame.frameModel = ent->client->clientMarkers[j].legsFrameModel; ent->legsFrame.oldFrame = ent->client->clientMarkers[j].legsOldFrame; ent->legsFrame.frame = ent->client->clientMarkers[j].legsFrame; ent->legsFrame.oldFrameTime = ent->client->clientMarkers[j].legsOldFrameTime; ent->legsFrame.frameTime = ent->client->clientMarkers[j].legsFrameTime; ent->legsFrame.yawAngle = ent->client->clientMarkers[j].legsYawAngle; ent->legsFrame.pitchAngle = ent->client->clientMarkers[j].legsPitchAngle; ent->legsFrame.yawing = ent->client->clientMarkers[j].legsYawing; ent->legsFrame.pitching = ent->client->clientMarkers[j].legsPitching; // forty - realistic hitboxes - time stamp for BuildHead/Leg ent->timeShiftTime = ent->client->clientMarkers[j].time; } trap_LinkEntity( ent ); }