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

📄 shapeimage.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
      *mat = getRenderTransform();
}

void ShapeBase::getRenderImageTransform(U32 imageSlot,StringTableEntry nodeName,MatrixF* mat)
{
   getRenderImageTransform( imageSlot, getNodeIndex( imageSlot, nodeName ), mat );
}

void ShapeBase::getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat)
{
   // Muzzle transform in world space
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock)
      getRenderImageTransform(imageSlot,image.dataBlock->muzzleNode,mat);
   else
      *mat = getRenderTransform();
}


void ShapeBase::getRetractionTransform(U32 imageSlot,MatrixF* mat)
{
   // Muzzle transform in world space
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock) {
      if (image.dataBlock->retractNode != -1)
         getImageTransform(imageSlot,image.dataBlock->retractNode,mat);
      else
         getImageTransform(imageSlot,image.dataBlock->muzzleNode,mat);
   } else {
      *mat = getTransform();
   }
}


void ShapeBase::getRenderRetractionTransform(U32 imageSlot,MatrixF* mat)
{
   // Muzzle transform in world space
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock) {
      if (image.dataBlock->retractNode != -1)
         getRenderImageTransform(imageSlot,image.dataBlock->retractNode,mat);
      else
         getRenderImageTransform(imageSlot,image.dataBlock->muzzleNode,mat);
   } else {
      *mat = getRenderTransform();
   }
}


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

S32 ShapeBase::getNodeIndex(U32 imageSlot,StringTableEntry nodeName)
{
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock)
      return image.dataBlock->shape->findNode(nodeName);
   else
      return -1;
}

// Modify muzzle if needed to aim at whatever is straight in front of eye.  Let the
// caller know if we actually modified the result.
bool ShapeBase::getCorrectedAim(const MatrixF& muzzleMat, VectorF* result)
{
   const F32 pullInD = 6.0;
   const F32 maxAdjD = 500;

   VectorF  aheadVec(0, maxAdjD, 0);

   MatrixF  eyeMat;
   Point3F  eyePos;
   getEyeTransform(&eyeMat);
   eyeMat.getColumn(3, &eyePos);
   eyeMat.mulV(aheadVec);
   Point3F  aheadPoint = (eyePos + aheadVec);

   // Should we check if muzzle point is really close to eye?  Does that happen?
   Point3F  muzzlePos;
   muzzleMat.getColumn(3, &muzzlePos);

   Point3F  collidePoint;
   VectorF  collideVector;
   disableCollision();
      RayInfo rinfo;
      if (getContainer()->castRay(eyePos, aheadPoint, 0xFFFFFFFF, &rinfo))
         collideVector = ((collidePoint = rinfo.point) - eyePos);
      else
         collideVector = ((collidePoint = aheadPoint) - eyePos);
   enableCollision();

   // For close collision we want to NOT aim at ground since we're bending
   // the ray here as it is.  But we don't want to pop, so adjust continuously.
   F32   lenSq = collideVector.lenSquared();
   if (lenSq < (pullInD * pullInD) && lenSq > 0.04)
   {
      F32   len = mSqrt(lenSq);
      F32   mid = pullInD;    // (pullInD + len) / 2.0;
      // This gives us point beyond to focus on-
      collideVector *= (mid / len);
      collidePoint = (eyePos + collideVector);
   }

   VectorF  muzzleToCollide = (collidePoint - muzzlePos);
   lenSq = muzzleToCollide.lenSquared();
   if (lenSq > 0.04)
   {
      muzzleToCollide *= (1 / mSqrt(lenSq));
      * result = muzzleToCollide;
      return true;
   }
   return false;
}

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

void ShapeBase::updateMass()
{
   if (mDataBlock) {
      F32 imass = 0;
      for (U32 i = 0; i < MaxMountedImages; i++) {
         MountedImage& image = mMountedImageList[i];
         if (image.dataBlock)
            imass += image.dataBlock->mass;
      }
      //
      mMass = mDataBlock->mass + imass;
      mOneOverMass = 1 / mMass;
   }
}

void ShapeBase::onImageRecoil(U32,ShapeBaseImageData::StateData::RecoilState)
{
}


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

void ShapeBase::setImage(U32 imageSlot, ShapeBaseImageData* imageData, StringHandle& skinNameHandle, bool loaded, bool ammo, bool triggerDown, bool target)
{
   MountedImage& image = mMountedImageList[imageSlot];

   // If we already have this datablock...
   if (image.dataBlock == imageData) {
      // Mark that there is not a datablock change pending.
      image.nextImage = InvalidImagePtr;
      // Change the skin handle if necessary.
      if (image.skinNameHandle != skinNameHandle) {
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
         if (!isGhost()) 
#endif
			{
            // Serverside, note the skin handle and tell the client.
            setMaskBits(ImageMaskN << imageSlot);
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
            image.skinNameHandle = skinNameHandle;
         }
         else {
#endif
            // Clientside, do the reskin.
            image.skinNameHandle = skinNameHandle;
            if (image.shapeInstance) {
               image.shapeInstance->reSkin(skinNameHandle);
            }
         }
      }
      return;
   }

   // Check to see if we need to delay image changes until state change.
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost()) 
#endif
	{
      if (imageData && image.dataBlock && !image.state->allowImageChange) {
         image.nextImage = imageData;
         image.nextSkinNameHandle = skinNameHandle;
         image.nextLoaded = loaded;
         return;
      }
   }

   // Mark that updates are happenin'.
   setMaskBits(ImageMaskN << imageSlot);

   // Notify script unmount since we're swapping datablocks.
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (image.dataBlock) 
#else
   if (image.dataBlock && !isGhost()) 
#endif
	{
      scriptCallback(imageSlot,"onUnmount");
   }

   // Stop anything currently going on with the image.
   resetImageSlot(imageSlot);

   // If we're just unselecting the current shape without swapping
   // in a new one, then bail.
   if (!imageData) {
      return;
   }

   // Otherwise, init the new shape.
   image.dataBlock = imageData;
   image.state = &image.dataBlock->state[0];
   image.skinNameHandle = skinNameHandle;
   image.shapeInstance = new TSShapeInstance(image.dataBlock->shape, isClientObject());
   if (isClientObject()) {
      if (image.shapeInstance) {
         image.shapeInstance->cloneMaterialList();
         image.shapeInstance->reSkin(skinNameHandle);
      }
   }
   image.loaded = loaded;
   image.ammo = ammo;
   image.triggerDown = triggerDown;
   image.target = target;

   // The server needs the shape loaded for muzzle mount nodes
   // but it doesn't need to run any of the animations.
   image.ambientThread = 0;
   image.animThread = 0;
   image.flashThread = 0;
   image.spinThread = 0;
   if (isGhost()) {
      if (image.dataBlock->isAnimated) {
         image.animThread = image.shapeInstance->addThread();
         image.shapeInstance->setTimeScale(image.animThread,0);
      }
      if (image.dataBlock->hasFlash) {
         image.flashThread = image.shapeInstance->addThread();
         image.shapeInstance->setTimeScale(image.flashThread,0);
      }
      if (image.dataBlock->ambientSequence != -1) {
         image.ambientThread = image.shapeInstance->addThread();
         image.shapeInstance->setTimeScale(image.ambientThread,1);
         image.shapeInstance->setSequence(image.ambientThread,
                                          image.dataBlock->ambientSequence,0);
      }
      if (image.dataBlock->spinSequence != -1) {
         image.spinThread = image.shapeInstance->addThread();
         image.shapeInstance->setTimeScale(image.spinThread,1);
         image.shapeInstance->setSequence(image.spinThread,
                                          image.dataBlock->spinSequence,0);
      }
   }

   // Set the image to its starting state.
   setImageState(imageSlot, 0, true);

   // Update the mass for the mount object.
   updateMass();

   // Notify script mount.
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost()) 
#endif
	{
      scriptCallback(imageSlot,"onMount");
   }

   // Done.
}


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

void ShapeBase::resetImageSlot(U32 imageSlot)
{
   // Clear out current image
   MountedImage& image = mMountedImageList[imageSlot];
   delete image.shapeInstance;
   image.shapeInstance = 0;
   if (image.animSound) {
      alxStop(image.animSound);
      image.animSound = 0;
   }
   for (S32 i = 0; i < MaxImageEmitters; i++) {
      MountedImage::ImageEmitter& em = image.emitter[i];
      if (bool(em.emitter)) {
         em.emitter->deleteWhenEmpty();
         em.emitter = 0;
      }
   }
   image.dataBlock = 0;
   image.nextImage = InvalidImagePtr;
   image.skinNameHandle = StringHandle();
   image.nextSkinNameHandle  = StringHandle();
   image.state = 0;
   image.delayTime = 0;
   image.ammo = false;
   image.triggerDown = false;
   image.loaded = false;
   image.lightStart = 0;
//   image.light.fLight.fType = TSLight::LightInvalid;
   updateMass();
}


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

bool ShapeBase::getImageTriggerState(U32 imageSlot)
{
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!mMountedImageList[imageSlot].dataBlock)
      return false;
#else
   if (isGhost() || !mMountedImageList[imageSlot].dataBlock)
      return false;
#endif
   return mMountedImageList[imageSlot].triggerDown;
}

void ShapeBase::setImageTriggerState(U32 imageSlot,bool trigger)
{
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if ( !mMountedImageList[imageSlot].dataBlock)
      return;
#else
   if (isGhost() || !mMountedImageList[imageSlot].dataBlock)
      return;
#endif
   MountedImage& image = mMountedImageList[imageSlot];

   if (trigger) {
      if (!image.triggerDown && image.dataBlock) {
         image.triggerDown = true;
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
         if (!isGhost()) 
#endif
			{
            setMaskBits(ImageMaskN << imageSlot);
            updateImageState(imageSlot,0);
         }
      }
   }
   else
      if (image.triggerDown) {
         image.triggerDown = false;
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
         if (!isGhost()) 
#endif
			{
            setMaskBits(ImageMaskN << imageSlot);
            updateImageState(imageSlot,0);
         }
      }
}


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

U32 ShapeBase::getImageFireState(U32 imageSlot)
{
   MountedImage& image = mMountedImageList[imageSlot];
   // If there is no fire state, then try state 0
   if (image.dataBlock && image.dataBlock->fireState != -1)
      return image.dataBlock->fireState;
   return 0;
}


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

void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
{
   if (!mMountedImageList[imageSlot].dataBlock)
      return;
   MountedImage& image = mMountedImageList[imageSlot];


   // The client never enters the initial fire state on its own, but it
   //  will continue to set that state...
   if (isGhost() && !force && newState == image.dataBlock->fireState) 
	{
      if (image.state != &image.dataBlock->state[newState])
         return;
   }

   // Eject shell casing on every state change

⌨️ 快捷键说明

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