コード例 #1
0
bool CObjectTunnelTrigger::KeepTunneling( TunnelPlayer *tunnel )
{
	if ( !tunnel || ( tunnel->player == NULL ) )
	{
		return false;
	}

	float remaining = tunnel->teleporttime - gpGlobals->curtime + 0.5f;
	remaining = max( 0.0f, remaining );

	tunnel->iremaining = (int)( remaining );

	if ( !tunnel->exitstarted )
	{
		if ( gpGlobals->curtime > tunnel->fadeintime )
		{
			tunnel->exitstarted = true;
			// Fade user screen to black
			color32 black = {0,0,0,255};
			UTIL_ScreenFade( tunnel->player, black, tunnel->fadetime, 0.0, FFADE_IN | FFADE_PURGE );

			// Move to tunnel exit spot now that we're half-way through teleport
			if ( m_hTunnelExit != NULL )
			{
				tunnel->player->EnableControl( true );
				tunnel->player->RemoveEffects( EF_NODRAW );

				// Change the player to non-solid before the teleport, so the physics system doesn't think he
				// actually moved this distance:
				int OriginalSolidFlags = tunnel->player->GetSolidFlags();
				tunnel->player->AddSolidFlags( FSOLID_NOT_SOLID);

				// Do a placement test to prevent the player from teleporting inside another player, the ground, or just to help
				// prevent badly placed tunnels from causing stuck situations.
				Vector vTarget = m_hTunnelExit->GetAbsOrigin();
				Vector vOriginal = vTarget; 

				if ( !EntityPlacementTest( tunnel->player, vOriginal, vTarget, true ) )
				{
					Warning("Couldn't place entity after tunnel teleport.\n");
				}


				tunnel->player->Teleport( &vTarget /*m_hTunnelExit->GetAbsOrigin()*/, &m_hTunnelExit->GetAbsAngles(), NULL );
				tunnel->player->SnapEyeAngles( m_hTunnelExit->GetAbsAngles() );
				tunnel->player->SetAbsVelocity( vec3_origin );

				// Restore the player's solid flags.
				tunnel->player->SetSolidFlags(OriginalSolidFlags);

			}
		}
// Can't quite do this because the player's weapons are still visible flying across the map even if
//  he is hidden
#if 0
		else if ( gpGlobals->curtime > tunnel->tunnelstarted + tunnel->fadetime )
		{
			float travel_time = tunnel->duration - 2 * tunnel->fadetime;
			if ( travel_time > 0.0f )
			{
				float f = ( gpGlobals->curtime - tunnel->tunnelstarted - tunnel->fadetime  ) / travel_time;
				f = clamp( f, 0.0f, 1.0f );
				if ( m_hTunnelExit != NULL )
				{
					Vector delta = m_hTunnelExit->GetAbsOrigin() - tunnel->startpos;
					Vector currentPos;
					VectorMA( tunnel->startpos, f, delta, currentPos );

					tunnel->player->Teleport( &currentPos, NULL, NULL );
				}
			}
		}
#endif
	}

	if ( tunnel->ilastremaining != tunnel->iremaining &&
		tunnel->needremainigcounter &&
		tunnel->iremaining >= 1 &&
		tunnel->player != NULL )
	{
		// Counter
		ClientPrint( tunnel->player, HUD_PRINTCENTER, UTIL_VarArgs("\nExiting tunnel in %d %s\n", tunnel->iremaining, tunnel->iremaining > 1 ? "seconds" : "second" ) );
	}

	tunnel->ilastremaining = tunnel->iremaining;

	// TODO: Play footstep or some other teleport sounds occasionaly to this player?

	bool done = ( gpGlobals->curtime > tunnel->teleporttime ) ? true : false;
	if ( done )
	{
		color32 black = {0,0,0,255};
		UTIL_ScreenFade( tunnel->player, black, 0.0f, 0.0f, FFADE_IN | FFADE_PURGE );

		tunnel->player->SetMoveType( MOVETYPE_WALK );
		tunnel->player->EnableControl( true );
		tunnel->player->RemoveEffects( EF_NODRAW );
		tunnel->player->RemoveSolidFlags( FSOLID_NOT_SOLID );

		// TODO:  Play an exit sound??
		OnTunnelTriggerEnd.FireOutput( tunnel->player, this );
	}

	return !done;
}