Exemple #1
0
// checks if the spot is clear of players
bool CSDKGameRules::IsSpawnPointValid( CBaseEntity *pSpot, CBasePlayer *pPlayer )
{
	if ( !pSpot->IsTriggered( pPlayer ) )
	{
		return false;
	}

	// Check if it is disabled by Enable/Disable
	CSpawnPoint *pSpawnPoint = dynamic_cast< CSpawnPoint * >( pSpot );
	if ( pSpawnPoint )
	{
		if ( pSpawnPoint->IsDisabled() )
		{
			return false;
		}
	}

	for (int i = 0; i < gpGlobals->maxClients; i++)
	{
		CBasePlayer *pOtherPlayer = UTIL_PlayerByIndex( i );
		if (!pOtherPlayer)
			continue;

		if (PlayerRelationship(pPlayer, pOtherPlayer) == GR_TEAMMATE)
			continue;

		if ((pSpot->GetAbsOrigin() - pOtherPlayer->GetAbsOrigin()).LengthSqr() > 512*512)
			continue;

		CSDKPlayer* pOtherSDKPlayer = ToSDKPlayer(pOtherPlayer);

		trace_t tr;
		UTIL_TraceLine( pSpot->WorldSpaceCenter(), pOtherSDKPlayer->WorldSpaceCenter(), MASK_VISIBLE_AND_NPCS, pPlayer, COLLISION_GROUP_NONE, &tr );
		if (tr.m_pEnt == pOtherPlayer)
			return false;
	}

	CBaseEntity* pGrenade = gEntList.FindEntityByClassname( NULL, "weapon_grenade" );
	while (pGrenade)
	{
		if ((pSpot->GetAbsOrigin() - pGrenade->GetAbsOrigin()).LengthSqr() < 500*500)
			return false;

		pGrenade = gEntList.FindEntityByClassname( pGrenade, "weapon_grenade" );
	}

	Vector mins = GetViewVectors()->m_vHullMin;
	Vector maxs = GetViewVectors()->m_vHullMax;

	Vector vTestMins = pSpot->GetAbsOrigin() + mins;
	Vector vTestMaxs = pSpot->GetAbsOrigin() + maxs;

	// First test the starting origin.
	return UTIL_IsSpaceEmpty( pPlayer, vTestMins, vTestMaxs );
}
void FPSCamera::Update(float dt)
{
	float forward[3], right[3], up[3];
	float diff[3];
	float movedir[2] = { 0, 0 };

	// rotate
	targetangles[1] = GLClamp(targetangles[1], -GL_HALF_PI, GL_HALF_PI);

	diff[0] = (targetangles[0] - anglecurve.curr[0]) * dt * ROTATIONAL_INVINTERTIA;
	diff[1] = (targetangles[1] - anglecurve.curr[1]) * dt * ROTATIONAL_INVINTERTIA;
	diff[2] = 0;

	anglecurve.extend(diff);
	
	// move
	GLVec3Set(diff, 0, 0, 0);

	if( state & State_Moving )
	{
		if( state & State_Left )
			movedir[0] = -1;

		if( state & State_Right )
			movedir[0] = 1;

		if( state & State_Forward )
			movedir[1] = 1;

		if( state & State_Backward )
			movedir[1] = -1;

		GetViewVectors(forward, right, up);

		if( forward[1] > 0.98f )
			GLVec3Set(forward, -up[0], -up[1], -up[2]);

		if( forward[1] < -0.98f )
			GLVec3Set(forward, up[0], up[1], up[2]);

		forward[1] = right[1] = 0;

		GLVec3Scale(forward, forward, movedir[1]);
		GLVec3Scale(right, right, movedir[0]);
		GLVec3Add(diff, forward, right);

		GLVec3Normalize(diff, diff);
		GLVec3Scale(diff, diff, MOVEMENT_SPEED);
	}

	// update body (NOTE: don't even try it with physics)
	CollisionData	data;
	RigidBody*		groundbody = 0;
	float			groundplane[4];
	float			hitparams[4];
	float			hitpos[3];
	float			prevpos[3];
	float			vel[3];
	float			deltavel[3] = { 0, 0, 0 };
	float			down[3] = { 0, -1, 0 };
	bool			wasonground = isonground;

	GLVec3Assign(prevpos, body->GetPosition());

	if( wasonground )
		body->SetVelocity(diff);
	
	body->Integrate(dt);

	// look for ground first
	groundbody = collworld->RayIntersect(hitparams, prevpos, down);
	isonground = false;

	if( groundbody && hitparams[3] >= 0 ) // && hitparams[1] > 0.64f
	{
		GLVec3Mad(hitpos, prevpos, down, hitparams[3]);
		GLPlaneFromRay(groundplane, hitpos, hitparams);
		GLVec3Subtract(vel, body->GetPosition(), prevpos);

		hitparams[3] = (CAMERA_RADIUS - groundplane[3] - GLVec3Dot(hitparams, prevpos)) / GLVec3Dot(hitparams, vel);

		if( hitparams[3] > -0.1f && hitparams[3] < 1.0f )
		{
			// resolve position
			body->ResolvePenetration(hitparams[3] * dt);
			isonground = true;

			// resolve velocity and integrate
			float length = GLVec3Length(diff);
			float cosa = GLVec3Dot(diff, hitparams);

			GLVec3Mad(diff, diff, hitparams, -cosa);

			if( fabs(length) > 1e-5f )
				GLVec3Scale(diff, diff, length / GLVec3Length(diff));

			body->SetVelocity(diff);
			body->IntegratePosition(dt);
		}
	}

	body->GetVelocity(vel);

	// now test every other object
	collworld->DetectCollisions(data, body);

	for( size_t i = 0; i < data.contacts.size(); ++i )
	{
		const Contact& contact = data.contacts[i];

		if( contact.body2 == groundbody )
			continue;

		if( contact.depth > 0 )
		{
			body->ResolvePenetration(contact);

			float rel_vel = GLVec3Dot(contact.normal, vel);
			float impulse = rel_vel;

			GLVec3Mad(deltavel, deltavel, contact.normal, -impulse);
		}
	}

	GLVec3Add(vel, vel, deltavel);
	body->SetVelocity(vel);
}