Esempio n. 1
0
//
// CL_PredicMove
//
void CL_PredictMove (void)
{
	if (noservermsgs)
		return;

	player_t *p = &consoleplayer();

	if (!p->tic || !p->mo)
		return;

	// Save player angle, viewheight,deltaviewheight and jumpTics.
	// Will use it later to predict movements
	int buf = gametic%MAXSAVETICS;
	
	cl_angle[buf] = p->mo->angle;
	cl_pitch[buf] = p->mo->pitch;
	cl_viewheight[buf] = p->viewheight;
	cl_deltaviewheight[buf] = p->deltaviewheight;
	cl_jumpTics[buf] = p->jumpTics;
	cl_reactiontime[buf] = p->mo->reactiontime;

	// Disable sounds, etc, during prediction
	predicting = true;

	// Set predictable items to their last received positions
	CL_ResetPlayers();
	CL_ResetSectors();

	int predtic = gametic - MAXSAVETICS;

	if(predtic < 0)
		predtic = 0;

	// Predict each tic
	while(predtic < gametic)
	{
		CL_PredictPlayers(predtic);
		CL_PredictSectors(predtic);

		++predtic;
	}

	predicting = false;

	CL_PredictPlayers(predtic);
	CL_PredictSectors(predtic);
}
Esempio n. 2
0
//
// CL_PredictMove
//
void CL_PredictMove (void)
{
	if (noservermsgs)
		return;

	player_t *p = &consoleplayer();

	if (!p->tic || !p->mo)
    {
        if (!p->spectator)
            return;
        
        // Predict sectors for local player who is a spectator
        CL_ResetSectors();
            
        int predtic = gametic - MAXSAVETICS;
            
        if(predtic < 0)
            predtic = 0;
            
        while(++predtic < gametic)
        {
            CL_PredictSectors(predtic);
        }
        
		return;      
    }
    
    #ifdef _PRED_DBG
    fixed_t origx, origy, origz;
    #endif

	// Save player angle, viewheight,deltaviewheight and jumpTics.
	// Will use it later to predict movements
	int buf = gametic%MAXSAVETICS;
	
	cl_angle[buf] = p->mo->angle;
	cl_pitch[buf] = p->mo->pitch;
	cl_viewheight[buf] = p->viewheight;
	cl_deltaviewheight[buf] = p->deltaviewheight;
	cl_jumpTics[buf] = p->jumpTics;
	cl_reactiontime[buf] = p->mo->reactiontime;
    cl_waterlevel[buf] = p->mo->waterlevel;

    #ifdef _PRED_DBG
    // Backup original position
	origx = p->mo->x;
	origy = p->mo->y;
	origz = p->mo->z;
    #endif
    
	// Disable sounds, etc, during prediction
	predicting = true;

	// Set predictable items to their last received positions
	CL_ResetPlayers();
	CL_ResetSectors();

	int predtic = gametic - MAXSAVETICS;

	if(predtic < 0)
		predtic = 0;

	// Predict each tic
	while(++predtic < gametic)
	{
		CL_PredictPlayers(predtic);
		CL_PredictSectors(predtic);
	}

	predicting = false;

	CL_PredictPlayers(predtic);
	// [Russell] - I don't think we need to call this as DThinker::RunThinkers()
	// will already run the moving sector thinkers after prediction
    //CL_PredictSectors(predtic);
    
    #ifdef _PRED_DBG
	if ((origx == p->mo->x) && (origy == p->mo->y) && (origz == p->mo->z))
    {
        Printf(PRINT_HIGH, "%d tics predicted\n", predtic);
    }
    else
    {
        Printf(PRINT_HIGH, "%d tics failed\n", predtic);
    }
    #endif
}
Esempio n. 3
0
//
// CL_PredictWorld
//
// Main function for client-side prediction.
// 
void CL_PredictWorld(void)
{
	if (gamestate != GS_LEVEL)
		return;

	player_t *p = &consoleplayer();

	if (!validplayer(*p) || !p->mo || noservermsgs || netdemo.isPaused())
		return;

	// tenatively tell the netgraph that our prediction was successful
	netgraph.setMisprediction(false);

	if (consoleplayer_id != displayplayer_id)
		CL_PredictSpying();

	// [SL] 2012-03-10 - Spectators can predict their position without server
	// correction.  Handle them as a special case and leave.
	if (consoleplayer().spectator)
	{
		CL_PredictSpectator();
		return;
	}
		
	if (p->tic <= 0)	// No verified position from the server
		return;

	// Disable sounds, etc, during prediction
	predicting = true;
	
	// Figure out where to start predicting from
	int predtic = consoleplayer().tic > 0 ? consoleplayer().tic: 0;
	// Last position update from the server is too old!
	if (predtic < gametic - MAXSAVETICS)
		predtic = gametic - MAXSAVETICS;
	
	// Save a snapshot of the player's state before prediction
	PlayerSnapshot prevsnap(p->tic, p);
	cl_savedsnaps[gametic % MAXSAVETICS] = prevsnap;

	// Move sectors to the last position received from the server
	if (cl_predictsectors)
		CL_ResetSectors();

	// Move the client to the last position received from the sever
	int snaptime = p->snapshots.getMostRecentTime();
	PlayerSnapshot snap = p->snapshots.getSnapshot(snaptime);
	snap.toPlayer(p);

	if (cl_predictlocalplayer)
	{
		while (++predtic < gametic)
		{
			if (cl_predictsectors)
				CL_PredictSectors(predtic);
			CL_PredictLocalPlayer(predtic);  
		}

		// If the player didn't just spawn or teleport, nudge the player from
		// his position last tic to this new corrected position.  This smooths the
		// view when there's a misprediction.
		if (snap.isContinuous())
		{
			PlayerSnapshot correctedprevsnap(p->tic, p);

			// Did we predict correctly?
			bool correct = (correctedprevsnap.getX() == prevsnap.getX()) &&
						   (correctedprevsnap.getY() == prevsnap.getY()) &&
						   (correctedprevsnap.getZ() == prevsnap.getZ());

			if (!correct)
			{
				// Update the netgraph concerning our prediction's error
				netgraph.setMisprediction(true);

				// Lerp from the our previous position to the correct position
				PlayerSnapshot lerpedsnap = P_LerpPlayerPosition(prevsnap, correctedprevsnap, cl_prednudge);	
				lerpedsnap.toPlayer(p);
			
				// [SL] 2012-04-26 - Snap directly to the corrected position in
				// the z direction.  This prevents players from floating above
				// lifts when the lift height is mispredicted.
				p->mo->z = correctedprevsnap.getZ();
			}
		}
	}

	predicting = false;

	// Run thinkers for current gametic
	if (cl_predictsectors)
		CL_PredictSectors(gametic);		
	CL_PredictLocalPlayer(gametic);
}