📄 explosion.cc
字号:
{
stream->writeInt((S32)(explosionScale.x * 100), 16);
stream->writeInt((S32)(explosionScale.y * 100), 16);
stream->writeInt((S32)(explosionScale.z * 100), 16);
}
stream->writeInt((S32)(playSpeed * 20), 14);
stream->writeRangedU32((U32)debrisThetaMin, 0, 180);
stream->writeRangedU32((U32)debrisThetaMax, 0, 180);
stream->writeRangedU32((U32)debrisPhiMin, 0, 360);
stream->writeRangedU32((U32)debrisPhiMax, 0, 360);
stream->writeRangedU32((U32)debrisNum, 0, 1000);
stream->writeRangedU32(debrisNumVariance, 0, 1000);
stream->writeInt((S32)(debrisVelocity * 10), 14);
stream->writeRangedU32((U32)(debrisVelocityVariance * 10), 0, 10000);
stream->writeInt(delayMS >> 5, 16);
stream->writeInt(delayVariance >> 5, 16);
stream->writeInt(lifetimeMS >> 5, 16);
stream->writeInt(lifetimeVariance >> 5, 16);
stream->write(offset);
stream->writeFlag( shakeCamera );
stream->write(camShakeFreq.x);
stream->write(camShakeFreq.y);
stream->write(camShakeFreq.z);
stream->write(camShakeAmp.x);
stream->write(camShakeAmp.y);
stream->write(camShakeAmp.z);
stream->write(camShakeDuration);
stream->write(camShakeRadius);
stream->write(camShakeFalloff);
for( S32 j=0; j<EC_NUM_DEBRIS_TYPES; j++ )
{
if( stream->writeFlag( debrisList[j] ) )
{
stream->writeRangedU32( debrisList[j]->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
S32 i;
for( i=0; i<EC_NUM_EMITTERS; i++ )
{
if( stream->writeFlag( emitterList[i] != NULL ) )
{
stream->writeRangedU32( emitterList[i]->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
for( i=0; i<EC_MAX_SUB_EXPLOSIONS; i++ )
{
if( stream->writeFlag( explosionList[i] != NULL ) )
{
stream->writeRangedU32( explosionList[i]->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
U32 count;
for(count = 0; count < EC_NUM_TIME_KEYS; count++)
if(times[i] >= 1)
break;
count++;
if(count > EC_NUM_TIME_KEYS)
count = EC_NUM_TIME_KEYS;
stream->writeRangedU32(count, 0, EC_NUM_TIME_KEYS);
for( i=0; i<count; i++ )
stream->writeFloat( times[i], 8 );
for( i=0; i<count; i++ )
{
stream->writeRangedU32((U32)(sizes[i].x * 100), 0, 16000);
stream->writeRangedU32((U32)(sizes[i].y * 100), 0, 16000);
stream->writeRangedU32((U32)(sizes[i].z * 100), 0, 16000);
}
// Dynamic light info
stream->writeFloat(lightStartRadius/MaxLightRadius, 8);
stream->writeFloat(lightEndRadius/MaxLightRadius, 8);
stream->writeFloat(lightStartColor.red,7);
stream->writeFloat(lightStartColor.green,7);
stream->writeFloat(lightStartColor.blue,7);
stream->writeFloat(lightEndColor.red,7);
stream->writeFloat(lightEndColor.green,7);
stream->writeFloat(lightEndColor.blue,7);
}
void ExplosionData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
dtsFileName = stream->readSTString();
if (stream->readFlag())
soundProfileId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
else
soundProfileId = 0;
if (stream->readFlag())
particleEmitterId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
else
particleEmitterId = 0;
particleDensity = stream->readInt(14);
stream->read(&particleRadius);
faceViewer = stream->readFlag();
if(stream->readFlag())
{
explosionScale.x = stream->readInt(16) / 100.0f;
explosionScale.y = stream->readInt(16) / 100.0f;
explosionScale.z = stream->readInt(16) / 100.0f;
}
else
explosionScale.set(1,1,1);
playSpeed = stream->readInt(14) / 20.0f;
debrisThetaMin = stream->readRangedU32(0, 180);
debrisThetaMax = stream->readRangedU32(0, 180);
debrisPhiMin = stream->readRangedU32(0, 360);
debrisPhiMax = stream->readRangedU32(0, 360);
debrisNum = stream->readRangedU32(0, 1000);
debrisNumVariance = stream->readRangedU32(0, 1000);
debrisVelocity = stream->readInt(14) / 10.0f;
debrisVelocityVariance = stream->readRangedU32(0, 10000) / 10.0f;
delayMS = stream->readInt(16) << 5;
delayVariance = stream->readInt(16) << 5;
lifetimeMS = stream->readInt(16) << 5;
lifetimeVariance = stream->readInt(16) << 5;
stream->read(&offset);
shakeCamera = stream->readFlag();
stream->read(&camShakeFreq.x);
stream->read(&camShakeFreq.y);
stream->read(&camShakeFreq.z);
stream->read(&camShakeAmp.x);
stream->read(&camShakeAmp.y);
stream->read(&camShakeAmp.z);
stream->read(&camShakeDuration);
stream->read(&camShakeRadius);
stream->read(&camShakeFalloff);
for( S32 j=0; j<EC_NUM_DEBRIS_TYPES; j++ )
{
if( stream->readFlag() )
{
debrisIDList[j] = (S32) stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
U32 i;
for( i=0; i<EC_NUM_EMITTERS; i++ )
{
if( stream->readFlag() )
{
emitterIDList[i] = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
for( S32 k=0; k<EC_MAX_SUB_EXPLOSIONS; k++ )
{
if( stream->readFlag() )
{
explosionIDList[k] = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
}
U32 count = stream->readRangedU32(0, EC_NUM_TIME_KEYS);
for( i=0; i<count; i++ )
times[i] = stream->readFloat(8);
for( i=0; i<count; i++ )
{
sizes[i].x = stream->readRangedU32(0, 16000) / 100.0f;
sizes[i].y = stream->readRangedU32(0, 16000) / 100.0f;
sizes[i].z = stream->readRangedU32(0, 16000) / 100.0f;
}
//
lightStartRadius = stream->readFloat(8) * MaxLightRadius;
lightEndRadius = stream->readFloat(8) * MaxLightRadius;
lightStartColor.red = stream->readFloat(7);
lightStartColor.green = stream->readFloat(7);
lightStartColor.blue = stream->readFloat(7);
lightEndColor.red = stream->readFloat(7);
lightEndColor.green = stream->readFloat(7);
lightEndColor.blue = stream->readFloat(7);
}
bool ExplosionData::preload(bool server, char errorBuffer[256])
{
if (Parent::preload(server, errorBuffer) == false)
return false;
if (dtsFileName && dtsFileName[0])
{
explosionShape = ResourceManager->load(dtsFileName);
if (!bool(explosionShape))
{
dSprintf(errorBuffer, sizeof(errorBuffer), "ExplosionData: Couldn't load shape \"%s\"", dtsFileName);
return false;
}
// Resolve animations
explosionAnimation = explosionShape->findSequence("ambient");
// Preload textures with a dummy instance...
TSShapeInstance* pDummy = new TSShapeInstance(explosionShape, !server);
delete pDummy;
}
else
{
explosionShape = NULL;
explosionAnimation = -1;
}
return true;
}
//--------------------------------------------------------------------------
Explosion::Explosion()
{
mTypeMask |= ExplosionObjectType;
mExplosionInstance = NULL;
mExplosionThread = NULL;
dMemset( mEmitterList, 0, sizeof( mEmitterList ) );
mFade = 1;
mDelayMS = 0;
mCurrMS = 0;
mEndingMS = 1000;
mActive = false;
mCollideType = 0;
mInitialNormal.set( 0.0, 0.0, 1.0 );
mRandAngle = sgRandom.randF( 0.0, 1.0 ) * M_PI * 2.0;
}
Explosion::~Explosion()
{
if( mExplosionInstance )
{
delete mExplosionInstance;
mExplosionInstance = NULL;
mExplosionThread = NULL;
}
}
void Explosion::setInitialState(const Point3F& point, const Point3F& normal, const F32 fade)
{
setPosition(point);
mInitialNormal = normal;
mFade = fade;
mFog = 0.0f;
}
//--------------------------------------------------------------------------
void Explosion::initPersistFields()
{
Parent::initPersistFields();
//
}
//--------------------------------------------------------------------------
bool Explosion::onAdd()
{
// first check if we have a server connection, if we dont then this is on the server
// and we should exit, then check if the parent fails to add the object
GameConnection* conn = GameConnection::getConnectionToServer();
if(!conn || !Parent::onAdd())
return false;
mDelayMS = mDataBlock->delayMS + sgRandom.randI( -mDataBlock->delayVariance, mDataBlock->delayVariance );
mEndingMS = mDataBlock->lifetimeMS + sgRandom.randI( -mDataBlock->lifetimeVariance, mDataBlock->lifetimeVariance );
if( mFabs( mDataBlock->offset ) > 0.001 )
{
MatrixF axisOrient = MathUtils::createOrientFromDir( mInitialNormal );
MatrixF trans = getTransform();
Point3F randVec;
randVec.x = sgRandom.randF( -1.0, 1.0 );
randVec.y = sgRandom.randF( 0.0, 1.0 );
randVec.z = sgRandom.randF( -1.0, 1.0 );
randVec.normalize();
randVec *= mDataBlock->offset;
axisOrient.mulV( randVec );
trans.setPosition( trans.getPosition() + randVec );
setTransform( trans );
}
// shake camera
if( mDataBlock->shakeCamera && isClientObject() )
{
// first check if explosion is near player
GameConnection* connection = GameConnection::getConnectionToServer();
ShapeBase *obj = connection->getControlObject();
bool applyShake = true;
if( obj )
{
ShapeBase* cObj = obj;
while((cObj = cObj->getControlObject()) != 0)
{
if(cObj->useObjsEyePoint())
{
applyShake = false;
break;
}
}
}
if( applyShake && obj )
{
VectorF diff = obj->getPosition() - getPosition();
F32 dist = diff.len();
if( dist < mDataBlock->camShakeRadius )
{
CameraShake *camShake = new CameraShake;
camShake->setDuration( mDataBlock->camShakeDuration );
camShake->setFrequency( mDataBlock->camShakeFreq );
F32 falloff = dist / mDataBlock->camShakeRadius;
falloff = 1 + falloff * 10.0;
falloff = 1.0 / (falloff * falloff);
VectorF shakeAmp = mDataBlock->camShakeAmp * falloff;
camShake->setAmplitude( shakeAmp );
camShake->setFalloff( mDataBlock->camShakeFalloff );
camShake->init();
gCamFXMgr.addFX( camShake );
}
}
}
// Try to explode!
if( mDelayMS == 0 && !explode() )
return false;
mRandomVal = sgRandom.randF();
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
if(!isServerObject())
#endif
{
gClientContainer.addObject(this);
gClientSceneGraph->addObjectToScene(this);
removeFromProcessList();
gClientProcessList.addObject(this);
NetConnection* pNC = NetConnection::getConnectionToServer();
AssertFatal(pNC != NULL, "Error, must have a connection to the server!");
pNC->addObject(this);
}
// Initialize the light structure and register as a dynamic light
if (mDataBlock->lightStartRadius != 0 || mDataBlock->lightEndRadius)
{
mLight.mType = LightInfo::Point;
mLight.mRadius = mDataBlock->lightStartRadius;
mLight.mColor = mDataBlock->lightStartColor;
Sim::getLightSet()->addObject(this);
}
return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -