Пример #1
0
/*
=================
CL_PredictMovement

Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
	int		frame = 1;
	int		ack, outgoing_command;
	int		current_command;
	int		current_command_mod;
	cl_entity_t	*player, *viewent;
	clientdata_t	*cd;

	if( cls.state != ca_active ) return;

	if( cls.demoplayback && cl.refdef.cmd != NULL )
	{
		// restore viewangles from cmd.angles
		VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles );
	}

	if( cl.refdef.paused || cls.key_dest == key_menu ) return;

	player = CL_GetLocalPlayer ();
	viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
	cd = &cl.frame.local.client;

	// unpredicted pure angled values converted into axis
	AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );

	if( !CL_IsPredicted( ))
	{	
		// run commands even if client predicting is disabled - client expected it
		clgame.pmove->runfuncs = true;
		CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
		return;
	}

	ack = cls.netchan.incoming_acknowledged;
	outgoing_command = cls.netchan.outgoing_sequence;

	ASSERT( cl.refdef.cmd != NULL );

	// setup initial pmove state
	CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
	clgame.pmove->runfuncs = false;

	while( 1 )
	{
		// we've run too far forward
		if( frame >= CL_UPDATE_BACKUP - 1 )
			break;

		// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
		current_command = ack + frame;
		current_command_mod = current_command & CL_UPDATE_MASK;

		// we've caught up to the current command.
		if( current_command >= outgoing_command )
			break;

		clgame.pmove->cmd = cl.cmds[current_command_mod];

		// motor!
		clgame.dllFuncs.pfnPlayerMove( clgame.pmove, false ); // run frames
		clgame.pmove->runfuncs = ( current_command > outgoing_command - 1 ) ? true : false;

		frame++;
	}

	CL_PostRunCmd( cl.refdef.cmd, frame );
		
	// copy results out for rendering
	VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
	VectorCopy( clgame.pmove->origin, cl.predicted_origin );
	VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
}
Пример #2
0
/*
=================
CL_PredictMovement

Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement()
{
	int	frame;
	int	ack, outgoing_command;
	int	current_command;
	int	current_command_mod;
	cl_entity_t	*player, *viewent;
	clientdata_t	*cd;

	if( cls.state != ca_active )
		return;

	if( cls.demoplayback && cl.refdef.cmd != NULL )
		VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles ); // restore viewangles from cmd.angles

	if(cl.refdef.paused /*|| cls.key_dest == key_menu*/)
		//return;

	player = CL_GetLocalPlayer ();
	viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
	cd = &cl.frame.local.client;

	// unpredicted pure angled values converted into axis
	AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );

	if( !CL_IsPredicted( ))
	{	
		// run commands even if client predicting is disabled - client expect it
		clgame.pmove->runfuncs = true;
		CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
		return;
	};

	ack = cls.netchan.incoming_acknowledged;
	outgoing_command = cls.netchan.outgoing_sequence;
	
	// if we are too far out of date, just freeze
	if(outgoing_command - ack >= CL_UPDATE_BACKUP)
	{
		//if(cl_showmiss->value)
			//Com_Printf ("exceeded CL_UPDATE_BACKUP\n");
		return;	
	};

	ASSERT( cl.refdef.cmd != NULL );

	// setup initial pmove state
	CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
	clgame.pmove->runfuncs = false;
	
	frame = 0;

	while(++ack < outgoing_command)
	{
		// we've run too far forward
		//if( frame >= CL_UPDATE_BACKUP - 1 )
		//	break;
		
		frame = ack & (CL_UPDATE_BACKUP - 1);

		// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
		current_command = ack + frame;
		current_command_mod = current_command & CL_UPDATE_MASK;

		// we've caught up to the current command
		// this was the most up to date command
		if(current_command >= outgoing_command)
			break;

		clgame.pmove->cmd = cl.cmds[current_command_mod];

		// Call the client dll player movement function (and it will call the PM_Move())
		clgame.dllFuncs.pfnPlayerMove(clgame.pmove, false); // run frames
		clgame.pmove->runfuncs = ( current_command > outgoing_command - 1 ) ? true : false; // Prevent to play sounds/etc more that once
		
		frame++;
	};

	CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );

	// copy results out for rendering
	VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
	VectorCopy( clgame.pmove->origin, cl.predicted_origin );
	VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
};