⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shapebase.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:

      if (store != mDamage) {
         updateDamageLevel();
         if (isServerObject()) {
            setMaskBits(DamageMask);
            char delta[100];
            dSprintf(delta,sizeof(delta),"%g",mDamage - store);
            Con::executef(mDataBlock,3,"onDamage",scriptThis(),delta);
         }
      }
   }
}

//----------------------------------------------------------------------------

static F32 sWaterDensity   = 1;
static F32 sWaterViscosity = 15;
static F32 sWaterCoverage  = 0;
static U32 sWaterType      = 0;
static F32 sWaterHeight    = 0.0f;

static void waterFind(SceneObject* obj, void* key)
{
   ShapeBase* shape = reinterpret_cast<ShapeBase*>(key);
   WaterBlock* wb = dynamic_cast<WaterBlock*>(obj);
   AssertFatal(wb != NULL, "Error, not a water block!");
   if (wb == NULL)
   {
      sWaterCoverage = 0;
      return;
   }

   if (wb->isPointSubmergedSimple(shape->getPosition()))
   {
      const Box3F& wbox = obj->getWorldBox();
      const Box3F& sbox = shape->getWorldBox();
      sWaterType = wb->getLiquidType();
      if (wbox.max.z < sbox.max.z)
         sWaterCoverage = (wbox.max.z - sbox.min.z) / (sbox.max.z - sbox.min.z);
      else
         sWaterCoverage = 1;

      sWaterViscosity = wb->getViscosity();
      sWaterDensity = wb->getDensity();
      sWaterHeight = wb->getSurfaceHeight();
   }
}

void physicalZoneFind(SceneObject* obj, void *key)
{
   ShapeBase* shape = reinterpret_cast<ShapeBase*>(key);
   PhysicalZone* pz = dynamic_cast<PhysicalZone*>(obj);
   AssertFatal(pz != NULL, "Error, not a physical zone!");
   if (pz == NULL || pz->testObject(shape) == false) {
      return;
   }

   if (pz->isActive()) {
      shape->mGravityMod   *= pz->getGravityMod();
      shape->mAppliedForce += pz->getForce();
   }
}

void findRouter(SceneObject* obj, void *key)
{
   if (obj->getTypeMask() & WaterObjectType)
      waterFind(obj, key);
   else if (obj->getTypeMask() & PhysicalZoneObjectType)
      physicalZoneFind(obj, key);
   else {
      AssertFatal(false, "Error, must be either water or physical zone here!");
   }
}

void ShapeBase::updateContainer()
{
   // Update container drag and buoyancy properties
   mDrag = mDataBlock->drag;
   mBuoyancy = 0;
   sWaterCoverage = 0;
   mGravityMod = 1.0;
   mAppliedForce.set(0, 0, 0);
   mContainer->findObjects(getWorldBox(), WaterObjectType|PhysicalZoneObjectType,findRouter,this);
   sWaterCoverage = mClampF(sWaterCoverage,0,1);
   mWaterCoverage = sWaterCoverage;
   mLiquidType    = sWaterType;
   mLiquidHeight  = sWaterHeight;
   if (mWaterCoverage >= 0.1f) {
      mDrag = mDataBlock->drag * sWaterViscosity * sWaterCoverage;
      mBuoyancy = (sWaterDensity / mDataBlock->density) * sWaterCoverage;
   }
}


//----------------------------------------------------------------------------

void ShapeBase::applyRepair(F32 amount)
{
   // Repair increases the repair reserve
   if (amount > 0 && ((mRepairReserve += amount) > mDamage))
      mRepairReserve = mDamage;
}

void ShapeBase::applyDamage(F32 amount)
{
   if (amount > 0)
      setDamageLevel(mDamage + amount);
}

F32 ShapeBase::getDamageValue()
{
   // Return a 0-1 damage value.
   return mDamage / mDataBlock->maxDamage;
}

void ShapeBase::updateDamageLevel()
{
   if (mDamageThread) {
      // mDamage is already 0-1 on the client
      if (mDamage >= mDataBlock->destroyedLevel) {
         if (getDamageState() == Destroyed)
            mShapeInstance->setPos(mDamageThread, 0);
         else
            mShapeInstance->setPos(mDamageThread, 1);
      } else {
         mShapeInstance->setPos(mDamageThread, mDamage / mDataBlock->destroyedLevel);
      }
   }
}


//----------------------------------------------------------------------------

void ShapeBase::setDamageState(DamageState state)
{
   if (mDamageState == state)
      return;

   const char* script = 0;
   const char* lastState = 0;

#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost()) 
#endif
	{
      if (state != getDamageState())
         setMaskBits(DamageMask);

      lastState = getDamageStateName();
      switch (state) {
         case Destroyed: {
            if (mDamageState == Enabled)
               setDamageState(Disabled);
            script = "onDestroyed";
            break;
         }
         case Disabled:
            if (mDamageState == Enabled)
               script = "onDisabled";
            break;
         case Enabled:
            script = "onEnabled";
            break;
      }
   }

   mDamageState = state;
   if (mDamageState != Enabled) {
      mRepairReserve = 0;
      mEnergy = 0;
   }
   if (script) {
      // Like to call the scripts after the state has been intialize.
      // This should only end up being called on the server.
      Con::executef(mDataBlock,3,script,scriptThis(),lastState);
   }
   updateDamageState();
   updateDamageLevel();
}

bool ShapeBase::setDamageState(const char* state)
{
   for (S32 i = 0; i < NumDamageStates; i++)
      if (!dStricmp(state,sDamageStateName[i])) {
         setDamageState(DamageState(i));
         return true;
      }
   return false;
}

const char* ShapeBase::getDamageStateName()
{
   return sDamageStateName[mDamageState];
}

void ShapeBase::updateDamageState()
{
   if (mHulkThread) {
      F32 pos = (mDamageState == Destroyed)? 1: 0;
      if (mShapeInstance->getPos(mHulkThread) != pos) {
         mShapeInstance->setPos(mHulkThread,pos);

         if (isClientObject())
            mShapeInstance->animate();
      }
   }
}


//----------------------------------------------------------------------------

void ShapeBase::blowUp()
{
   Point3F center;
   mObjBox.getCenter(&center);
   center += getPosition();
   MatrixF trans = getTransform();
   trans.setPosition( center );

   // explode
   Explosion* pExplosion = NULL;

   if( pointInWater( (Point3F &)center ) && mDataBlock->underwaterExplosion )
   {
      pExplosion = new Explosion;
      pExplosion->onNewDataBlock(mDataBlock->underwaterExplosion);
   }
   else
   {
      if (mDataBlock->explosion)
      {
         pExplosion = new Explosion;
         pExplosion->onNewDataBlock(mDataBlock->explosion);
      }
   }

   if( pExplosion )
   {
      pExplosion->setTransform(trans);
      pExplosion->setInitialState(center, damageDir);
      if (pExplosion->registerObject() == false)
      {
         Con::errorf(ConsoleLogEntry::General, "ShapeBase(%s)::explode: couldn't register explosion",
                     mDataBlock->getName() );
         delete pExplosion;
         pExplosion = NULL;
      }
   }

   TSShapeInstance *debShape = NULL;

   if( mDataBlock->debrisShape.isNull() )
   {
      return;
   }
   else
   {
      debShape = new TSShapeInstance( mDataBlock->debrisShape, true);
   }


   Vector< TSPartInstance * > partList;
   TSPartInstance::breakShape( debShape, 0, partList, NULL, NULL, 0 );

   if( !mDataBlock->debris )
   {
      mDataBlock->debris = new DebrisData;
   }

   // cycle through partlist and create debris pieces
   for( U32 i=0; i<partList.size(); i++ )
   {
      //Point3F axis( 0.0, 0.0, 1.0 );
      Point3F randomDir = MathUtils::randomDir( damageDir, 0, 50 );

      Debris *debris = new Debris;
      debris->setPartInstance( partList[i] );
      debris->init( center, randomDir );
      debris->onNewDataBlock( mDataBlock->debris );
      debris->setTransform( trans );

      if( !debris->registerObject() )
      {
         Con::warnf( ConsoleLogEntry::General, "Could not register debris for class: %s", mDataBlock->getName() );
         delete debris;
         debris = NULL;
      }
      else
      {
         debShape->incDebrisRefCount();
      }
   }

   damageDir.set(0, 0, 1);
}


//----------------------------------------------------------------------------
void ShapeBase::mountObject(ShapeBase* obj,U32 node)
{
//   if (obj->mMount.object == this)
//      return;
   if (obj->mMount.object)
      obj->unmount();

   // Since the object is mounting to us, nothing should be colliding with it for a while
   obj->mConvexList->nukeList();

   obj->mMount.object = this;
   obj->mMount.node = (node >= 0 && node < ShapeBaseData::NumMountPoints)? node: 0;
   obj->mMount.link = mMount.list;
   mMount.list = obj;
   if (obj != getControllingObject())
      obj->processAfter(this);
   obj->deleteNotify(this);
   obj->setMaskBits(MountedMask);
   obj->onMount(this,node);
}


void ShapeBase::unmountObject(ShapeBase* obj)
{
   if (obj->mMount.object == this) {

      // Find and unlink the object
      for(ShapeBase **ptr = & mMount.list; (*ptr); ptr = &((*ptr)->mMount.link) )
      {
         if(*ptr == obj)
         {
            *ptr = obj->mMount.link;
            break;
         }
      }
      if (obj != getControllingObject())
         obj->clearProcessAfter();
      obj->clearNotify(this);
      obj->mMount.object = 0;
      obj->mMount.link = 0;
      obj->setMaskBits(MountedMask);
      obj->onUnmount(this,obj->mMount.node);
   }
}

void ShapeBase::unmount()
{
   if (mMount.object)
      mMount.object->unmountObject(this);
}

void ShapeBase::onMount(ShapeBase* obj,S32 node)
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost()) 
#endif
	{
      char buff1[32];
      dSprintf(buff1,sizeof(buff1),"%d",node);
      Con::executef(mDataBlock,4,"onMount",scriptThis(),obj->scriptThis(),buff1);
   }
}

void ShapeBase::onUnmount(ShapeBase* obj,S32 node)
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost()) 
#endif
	{
      char buff1[32];
      dSprintf(buff1,sizeof(buff1),"%d",node);
      Con::executef(mDataBlock,4,"onUnmount",scriptThis(),obj->scriptThis(),buff1);
   }
}

S32 ShapeBase::getMountedObjectCount()
{
   S32 count = 0;
   for (ShapeBase* itr = mMount.list; itr; itr = itr->mMount.link)
      count++;
   return count;
}

ShapeBase* ShapeBase::getMountedObject(S32 idx)
{
   if (idx >= 0) {
      S32 count = 0;
      for (ShapeBase* itr = mMount.list; itr; itr = itr->mMount.link)
         if (count++ == idx)
            return itr;
   }
   return 0;
}

S32 ShapeBase::getMountedObjectNode(S32 idx)
{
   if (idx >= 0) {
      S32 count = 0;
      for (ShapeBase* itr = mMount.list; itr; itr = itr->mMount.link)
         if (count++ == idx)
            return itr->mMount.node;
   }
   return -1;
}

ShapeBase* ShapeBase::getMountNodeObject(S32 node)
{
   for (ShapeBase* itr = mMount.list; itr; itr = itr->mMount.link)
      if (itr->mMount.node == node)
         return itr;
   return 0;
}

Point3F ShapeBase::getAIRepairPoint()
{
   if (mDataBlock->mountPointNode[ShapeBaseData::AIRepairNode] < 0)
        return Point3F(0, 0, 0);
   MatrixF xf(true);
   getMountTransform(ShapeBaseData::AIRepairNode,&xf);
   Point3F pos(0, 0, 0);
   xf.getColumn(3,&pos);
   return pos;
}

//----------------------------------------------------------------------------

void ShapeBase::getEyeTransform(MatrixF* mat)
{
   // Returns eye to world space transform
   S32 eyeNode = mDataBlock->eyeNode;
   if (eyeNode != -1)
      mat->mul(getTransform(), mShapeInstance->mNodeTransforms[eyeNode]);
   else
      *mat = getTransform();
}

void ShapeBase::getRenderEyeTransform(MatrixF* mat)
{
   // Returns eye to world space transform
   S32 eyeNode = mDataBlock->eyeNode;
   if (eyeNode != -1)
      mat->mul(getRenderTransform(), mShapeInstance->mNodeTransforms[eyeNode]);
   else
      *mat = getRenderTransform();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -