Merge pull request #387 from lukaspj/Projectile-Explosion-Change

Let projectiles collide with objects without being armed.
This commit is contained in:
SilentMike 2013-08-04 21:44:42 -07:00
commit 40b29c994d

View file

@ -1106,68 +1106,61 @@ void Projectile::simulate( F32 dt )
if ( isServerObject() && ( rInfo.object->getTypeMask() & csmStaticCollisionMask ) == 0 )
setMaskBits( BounceMask );
MatrixF xform( true );
xform.setColumn( 3, rInfo.point );
setTransform( xform );
mCurrPosition = rInfo.point;
mCurrVelocity = Point3F::Zero;
// Get the object type before the onCollision call, in case
// the object is destroyed.
U32 objectType = rInfo.object->getTypeMask();
// re-enable the collision response on the source object since
// we need to process the onCollision and explode calls
if ( disableSourceObjCollision )
mSourceObject->enableCollision();
// Ok, here is how this works:
// onCollision is called to notify the server scripts that a collision has occurred, then
// a call to explode is made to start the explosion process. The call to explode is made
// twice, once on the server and once on the client.
// The server process is responsible for two things:
// 1) setting the ExplosionMask network bit to guarantee that the client calls explode
// 2) initiate the explosion process on the server scripts
// The client process is responsible for only one thing:
// 1) drawing the appropriate explosion
// It is possible that during the processTick the server may have decided that a hit
// has occurred while the client prediction has decided that a hit has not occurred.
// In this particular scenario the client will have failed to call onCollision and
// explode during the processTick. However, the explode function will be called
// during the next packet update, due to the ExplosionMask network bit being set.
// onCollision will remain uncalled on the client however, therefore no client
// specific code should be placed inside the function!
onCollision( rInfo.point, rInfo.normal, rInfo.object );
// Next order of business: do we explode on this hit?
if ( mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0 )
{
MatrixF xform( true );
xform.setColumn( 3, rInfo.point );
setTransform( xform );
mCurrPosition = rInfo.point;
mCurrVelocity = Point3F::Zero;
// Get the object type before the onCollision call, in case
// the object is destroyed.
U32 objectType = rInfo.object->getTypeMask();
// re-enable the collision response on the source object since
// we need to process the onCollision and explode calls
if ( disableSourceObjCollision )
mSourceObject->enableCollision();
// Ok, here is how this works:
// onCollision is called to notify the server scripts that a collision has occurred, then
// a call to explode is made to start the explosion process. The call to explode is made
// twice, once on the server and once on the client.
// The server process is responsible for two things:
// 1) setting the ExplosionMask network bit to guarantee that the client calls explode
// 2) initiate the explosion process on the server scripts
// The client process is responsible for only one thing:
// 1) drawing the appropriate explosion
// It is possible that during the processTick the server may have decided that a hit
// has occurred while the client prediction has decided that a hit has not occurred.
// In this particular scenario the client will have failed to call onCollision and
// explode during the processTick. However, the explode function will be called
// during the next packet update, due to the ExplosionMask network bit being set.
// onCollision will remain uncalled on the client however, therefore no client
// specific code should be placed inside the function!
onCollision( rInfo.point, rInfo.normal, rInfo.object );
explode( rInfo.point, rInfo.normal, objectType );
// break out of the collision check, since we've exploded
// we don't want to mess with the position and velocity
}
else
if ( mDataBlock->isBallistic )
{
if ( mDataBlock->isBallistic )
{
// Otherwise, this represents a bounce. First, reflect our velocity
// around the normal...
Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);
mCurrVelocity = bounceVel;
// Otherwise, this represents a bounce. First, reflect our velocity
// around the normal...
Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);
mCurrVelocity = bounceVel;
// Add in surface friction...
Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal);
mCurrVelocity -= tangent * mDataBlock->bounceFriction;
// Add in surface friction...
Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal);
mCurrVelocity -= tangent * mDataBlock->bounceFriction;
// Now, take elasticity into account for modulating the speed of the grenade
mCurrVelocity *= mDataBlock->bounceElasticity;
// Now, take elasticity into account for modulating the speed of the grenade
mCurrVelocity *= mDataBlock->bounceElasticity;
// Set the new position to the impact and the bounce
// will apply on the next frame.
//F32 timeLeft = 1.0f - rInfo.t;
newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
}
// Set the new position to the impact and the bounce
// will apply on the next frame.
//F32 timeLeft = 1.0f - rInfo.t;
newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
}
}
@ -1444,4 +1437,4 @@ DefineEngineMethod(Projectile, presimulate, void, (F32 seconds), (1.0f),
"@note This function is not called if the SimObject::hidden is true.")
{
object->simulate( seconds );
}
}