Beispiel #1
0
int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
										const idVec3 &newOrigin, const idVec3 &move ) {
	trace_t		trace;
	idVec3		checkMove;
	idVec3		oldOrigin;
	idPhysics	*physics;

	physics = check->GetPhysics();

#ifdef TRANSLATIONAL_PUSH_DEBUG
	bool startsolid = false;
	if ( physics->ClipContents( clipModel ) ) {
		startsolid = true;
	}
#endif

	results.fraction = 1.0f;
	results.endpos = newOrigin;
	results.endAxis = clipModel->GetAxis();
	memset( &results.c, 0, sizeof( results.c ) );

	// always pushed when standing on the pusher
	if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, move );
		// if there is a collision
		if ( trace.fraction < 1.0f ) {
			// vector along which the entity is pushed
			checkMove = move * trace.fraction;
			// test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher
			ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) );
			// if there is a collision
			if ( results.fraction < 1.0f ) {

				// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

				results.c.normal = -results.c.normal;
				results.c.dist = -results.c.dist;

				// the entity will be crushed between the pusher and some other entity
				return PUSH_BLOCKED;
			}
		}
		else {
			// vector along which the entity is pushed
			checkMove = move;
		}
	}
	else {
		// move entity in reverse only colliding with pusher
		ClipEntityTranslation( results, check, clipModel, NULL, -move );
		// if no collision with the pusher then the entity is not pushed by the pusher
		if ( results.fraction >= 1.0f ) {
			return PUSH_NO;
		}
		// vector along which the entity is pushed
		checkMove = move * (1.0f - results.fraction);
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, checkMove );
		// if there is a collisions
		if ( trace.fraction < 1.0f ) {

			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			// FIXME: try to push the blocking entity as well ?
			// FIXME: handle sliding along more than one collision plane ?
			// FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map"

/*
			oldOrigin = physics->GetOrigin();

			// movement still remaining
			checkMove *= (1.0f - trace.fraction);

			// project the movement along the collision plane
			if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) {
				return PUSH_BLOCKED;
			}
			checkMove *= 1.001f;

			// move entity from collision point along the collision plane
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, NULL, NULL, checkMove );

			if ( trace.fraction < 1.0f ) {
				physics->SetOrigin( oldOrigin );
				return PUSH_BLOCKED;
			}

			checkMove = trace.endpos - oldOrigin;

			// move entity in reverse only colliding with pusher
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, clipModel, NULL, -move );

			physics->SetOrigin( oldOrigin );
*/
			if ( trace.fraction < 1.0f ) {
				return PUSH_BLOCKED;
			}
		}
	}

	SaveEntityPosition( check );

	// translate the entity
	physics->Translate( checkMove );

#ifdef TRANSLATIONAL_PUSH_DEBUG
	// set the pusher in the translated position
	clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() );
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	return PUSH_OK;
}
Beispiel #2
0
int idPush::TryTranslatePushEntity( trace_t &results, idEntity *check, idClipModel *clipModel, const int flags,
										const idVec3 &newOrigin, const idVec3 &move ) {
	trace_t		trace;
	idVec3		checkMove;
	idVec3		oldOrigin;

	idPhysics* physics = check->GetPhysics();

#ifdef TRANSLATIONAL_PUSH_DEBUG
	bool startsolid = false;
	if ( physics->ClipContents( clipModel ) ) {
		startsolid = true;
	}
#endif

	results.fraction = 1.0f;
	results.endpos = newOrigin;
	results.endAxis = clipModel->GetAxis();
	memset( &results.c, 0, sizeof( results.c ) );

	// always pushed when standing on the pusher
	if ( physics->IsGroundClipModel( clipModel->GetEntity()->entityNumber, clipModel->GetId() ) ) {
		// move the entity colliding with all other entities except the pusher itself

		// grayman #3029 - if this is an AI with attachments, we have to make them
		// temporarily non-solid for the translation check. Though weapons don't
		// impede movement, pauldrons do.

		if ( check->IsType(idAI::Type) )
		{
			idAI* checkAI = static_cast<idAI*>(check);

			checkAI->SaveAttachmentContents();
			checkAI->SetAttachmentContents(0);
			ClipEntityTranslation( trace, check, NULL, clipModel, move );
			checkAI->RestoreAttachmentContents();
		}
		else
		{
			ClipEntityTranslation( trace, check, NULL, clipModel, move );
		}

		// if there is a collision
		if ( trace.fraction < 1.0f ) {
			// vector along which the entity is pushed
			checkMove = move * trace.fraction;
			// test if the entity can stay at it's partly pushed position by moving the entity in reverse only colliding with pusher
			ClipEntityTranslation( results, check, clipModel, NULL, -(move - checkMove) );
			// if there is a collision
			if ( results.fraction < 1.0f ) {

				// FIXME: try to push the blocking entity as well or try to slide along collision plane(s)?

				results.c.normal = -results.c.normal;
				results.c.dist = -results.c.dist;

				// the entity will be crushed between the pusher and some other entity
				return PUSH_BLOCKED;
			}
		}
		else {
			// vector along which the entity is pushed
			checkMove = move;
		}
	}
	else
	{
		// move entity in reverse only colliding with pusher
		ClipEntityTranslation( results, check, clipModel, NULL, -move );
		// if no collision with the pusher then the entity is not pushed by the pusher
		if ( results.fraction >= 1.0f )
		{
			return PUSH_NO;
		}

		
		// greebo: At this point, the pushes knows that the check entity is in the way
		// Normally, the pusher tries to rotate the entity to see if the entity itself 
		// is colliding with anything else, but for players, we want to (optionally) skip that.
		if ((flags & PUSHFL_NOPLAYER) && check->IsType(idPlayer::Type)) 
		{
			// We are colliding with a player and are not allowed to push it, return BLOCKED
			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			return PUSH_BLOCKED;
		}

		// vector along which the entity is pushed
		checkMove = move * (1.0f - results.fraction);
		// move the entity colliding with all other entities except the pusher itself
		ClipEntityTranslation( trace, check, NULL, clipModel, checkMove );
		// if there is a collisions
		if ( trace.fraction < 1.0f ) {

			results.c.normal = -results.c.normal;
			results.c.dist = -results.c.dist;

			// FIXME: try to push the blocking entity as well ?
			// FIXME: handle sliding along more than one collision plane ?
			// FIXME: this code has issues, player pushing box into corner in "maps/mre/aaron/test.map"

/*
			oldOrigin = physics->GetOrigin();

			// movement still remaining
			checkMove *= (1.0f - trace.fraction);

			// project the movement along the collision plane
			if ( !checkMove.ProjectAlongPlane( trace.c.normal, 0.1f, 1.001f ) ) {
				return PUSH_BLOCKED;
			}
			checkMove *= 1.001f;

			// move entity from collision point along the collision plane
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, NULL, NULL, checkMove );

			if ( trace.fraction < 1.0f ) {
				physics->SetOrigin( oldOrigin );
				return PUSH_BLOCKED;
			}

			checkMove = trace.endpos - oldOrigin;

			// move entity in reverse only colliding with pusher
			physics->SetOrigin( trace.endpos );
			ClipEntityTranslation( trace, check, clipModel, NULL, -move );

			physics->SetOrigin( oldOrigin );
*/
			if ( trace.fraction < 1.0f ) {
				return PUSH_BLOCKED;
			}
		}
	}

	SaveEntityPosition( check );

	// translate the entity
	physics->Translate( checkMove );

#ifdef TRANSLATIONAL_PUSH_DEBUG
	// set the pusher in the translated position
	clipModel->Link( gameLocal.clip, clipModel->GetEntity(), clipModel->GetId(), newOrigin, clipModel->GetAxis() );
	if ( physics->ClipContents( clipModel ) ) {
		if ( !startsolid ) {
			int bah = 1;
		}
	}
#endif

	return PUSH_OK;
}