/*
=====================
idPhysics_Monster::SlideMove
=====================
*/
monsterMoveResult_t idPhysics_Monster::SlideMove(idVec3 &start, idVec3 &velocity, const idVec3 &delta)
{
	int i;
	trace_t tr;
	idVec3 move;

	blockingEntity = NULL;
	move = delta;

	for (i = 0; i < 3; i++) {
		gameLocal.clip.Translation(tr, start, start + move, clipModel, clipModel->GetAxis(), clipMask, self);

		start = tr.endpos;

		if (tr.fraction == 1.0f) {
			if (i > 0) {
				return MM_SLIDING;
			}

			return MM_OK;
		}

		if (tr.c.entityNum != ENTITYNUM_NONE) {
			blockingEntity = gameLocal.entities[ tr.c.entityNum ];
		}

		// clip the movement delta and velocity
		move.ProjectOntoPlane(tr.c.normal, OVERCLIP);
		velocity.ProjectOntoPlane(tr.c.normal, OVERCLIP);
	}

	return MM_BLOCKED;
}
예제 #2
0
/*
================
rvPhysics_Particle::SlideMove
================
*/
bool rvPhysics_Particle::SlideMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) {
	int		i;
	trace_t tr;
	idVec3	move;
	bool collide, rtnValue = false;

	move = delta;
	for( i = 0; i < 3; i++ ) { // be sure if you change this upper value in the for() to update the exit condition below!!!!!
		gameLocal.Translation( self, tr, start, start + move, clipModel, clipModel->GetAxis(), clipMask, self, extraPassEntity );

		start = tr.endpos;

		if ( tr.fraction == 1.0f ) {
			if ( i > 0 ) {
				return false;
			}
			return true;
		}
		
		bool hitTeleporter = false;
		
		// let the entity know about the collision
		collide = self->Collide( tr, current.velocity, hitTeleporter );
		
		idEntity* ent;
		ent = gameLocal.entities[tr.c.entityNum];
		assert ( ent );
		
		// If we hit water just clip the move for now and keep on going
		if ( ent->GetPhysics()->GetContents() & CONTENTS_WATER ) {
			// Make sure we dont collide with water again
			clipMask &= ~CONTENTS_WATER;
			
			current.inWater = true;
			
			// Allow the loop to go one more round to push us through the water
			i--;
						
			velocity *= 0.4f;
						
			move.ProjectOntoPlane( tr.c.normal, PRT_OVERCLIP );
			continue;
		// bounce the projectile
		} else if ( !current.inWater && allowBounce && bouncyness ) {
			if ( !hitTeleporter ) {
				float dot;
				move = tr.endpos;
				dot = DotProduct( velocity, tr.c.normal );
				velocity  = ( velocity - ( 2.0f * dot * tr.c.normal ) ) * bouncyness;
			}
			return true;
//RAVEN BEGIN
//jshepard: tr.c.material can (did) crash here if null
		} else if ( allowBounce && tr.c.material && (tr.c.material->GetSurfaceFlags ( ) & SURF_BOUNCE) ) {
//RAVEN END
			float dot;
			move = tr.endpos;
			dot = DotProduct( velocity, tr.c.normal );
			velocity  = ( velocity - ( 2.0f * dot * tr.c.normal ) );
			return true;
		}			
// RAVEN BEGIN
// dluetscher: removed redundant trace calls
		else {
			i = 4;
			rtnValue = true;
		}
// RAVEN END

		// clip the movement delta and velocity
		if( collide ) {
			move.ProjectOntoPlane( tr.c.normal, PRT_OVERCLIP );
			velocity.ProjectOntoPlane( tr.c.normal, PRT_OVERCLIP );
		}
	}

	return rtnValue;
}