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

📄 shapeimage.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
   ShapeBaseImageData::StateData& nextStateData = image.dataBlock->state[newState];
   if (isGhost() && nextStateData.ejectShell) {
      ejectShellCasing( imageSlot );
   }


   // Server must animate the shape if it is a firestate...
   if (newState == image.dataBlock->fireState && isServerObject())
      mShapeInstance->animate();

   // If going back into the same state, just reset the timer
   // and invoke the script callback
   if (!force && image.state == &image.dataBlock->state[newState]) {
      image.delayTime = image.state->timeoutValue;
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
      if (image.state->script)
#else
      if (image.state->script && !isGhost())
#endif
         scriptCallback(imageSlot,image.state->script);

      // If this is a flash sequence, we need to select a new position for the
      //  animation if we're returning to that state...
      if (image.animThread && image.state->sequence != -1 && image.state->flashSequence) {
         F32 randomPos = Platform::getRandom();
         image.shapeInstance->setPos(image.animThread, randomPos);
         image.shapeInstance->setTimeScale(image.animThread, 0);
         if (image.flashThread)
            image.shapeInstance->setPos(image.flashThread, 0);
      }

      return;
   }

   F32 lastDelay = image.delayTime;
   ShapeBaseImageData::StateData& lastState = *image.state;
   image.state = &image.dataBlock->state[newState];

   //
   // Do state cleanup first...
   //
   ShapeBaseImageData& imageData = *image.dataBlock;
   ShapeBaseImageData::StateData& stateData = *image.state;

   // Stop any looping sounds or animations use in the last state.
   if (image.animSound && image.animLoopingSound) {
      alxStop(image.animSound);
      image.animSound = 0;
   }

   // Mount pending images
   if (image.nextImage != InvalidImagePtr && stateData.allowImageChange) {
      setImage(imageSlot,image.nextImage,image.nextSkinNameHandle,image.nextLoaded);
      return;
   }

   // Reset cyclic sequences back to the first frame to turn it off
   // (the first key frame should be it's off state).
   if (image.animThread && image.dataBlock->shape->sequences[image.shapeInstance->getSequence(image.animThread)].isCyclic()) {
      image.shapeInstance->setPos(image.animThread,0);
      image.shapeInstance->setTimeScale(image.animThread,0);
   }
   if (image.flashThread) {
      image.shapeInstance->setPos(image.flashThread,0);
      image.shapeInstance->setTimeScale(image.flashThread,0);
   }

   // Check for immediate transitions
   S32 ns;
   if ((ns = stateData.transition.loaded[image.loaded]) != -1) {
      setImageState(imageSlot,ns);
      return;
   }
   //if (!imageData.usesEnergy)
      if ((ns = stateData.transition.ammo[image.ammo]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
   if ((ns = stateData.transition.target[image.target]) != -1) {
      setImageState(imageSlot, ns);
      return;
   }
   if ((ns = stateData.transition.wet[image.wet]) != -1) {
      setImageState(imageSlot, ns);
      return;
   }
   if ((ns = stateData.transition.trigger[image.triggerDown]) != -1) {
      setImageState(imageSlot,ns);
      return;
   }

   //
   // Initialize the new state...
   //
   image.delayTime = stateData.timeoutValue;
   if (stateData.loaded != ShapeBaseImageData::StateData::IgnoreLoaded)
      image.loaded = stateData.loaded == ShapeBaseImageData::StateData::Loaded;
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (newState == imageData.fireState) 
#else
   if (!isGhost() && newState == imageData.fireState) 
#endif
	{
      setMaskBits(ImageMaskN << imageSlot);
      image.fireCount = (image.fireCount + 1) & 0x7;
   }

   // Apply recoil
   if (stateData.recoil != ShapeBaseImageData::StateData::NoRecoil)
      onImageRecoil(imageSlot,stateData.recoil);

   // Play sound
   if (stateData.sound && isGhost()) {
      Point3F vel = getVelocity();
      image.animSound = alxPlay(stateData.sound, &getRenderTransform(), &vel);
      ALint value = 0;
      alxGetSourcei(image.animSound, AL_LOOPING, &value);
      image.animLoopingSound = (value == AL_TRUE);
   }

   // Play animation
   if (image.animThread && stateData.sequence != -1) {
      image.shapeInstance->setSequence(image.animThread,stateData.sequence,
                                       stateData.direction ? 0 : 1);
      if (stateData.flashSequence == false) {
         F32 timeScale = (stateData.scaleAnimation && stateData.timeoutValue) ?
            image.shapeInstance->getDuration(image.animThread) / stateData.timeoutValue :
            1;
         image.shapeInstance->setTimeScale(image.animThread, stateData.direction ? timeScale :
                                           -timeScale);
      } else {
         F32 randomPos = Platform::getRandom();
         image.shapeInstance->setPos(image.animThread, randomPos);
         image.shapeInstance->setTimeScale(image.animThread, 0);

         image.shapeInstance->setSequence(image.flashThread, stateData.sequenceVis, 0);
         image.shapeInstance->setPos(image.flashThread, 0);
         F32 timeScale = (stateData.scaleAnimation && stateData.timeoutValue) ?
            image.shapeInstance->getDuration(image.animThread) / stateData.timeoutValue :
            1;
         image.shapeInstance->setTimeScale(image.flashThread, timeScale);
      }
   }

   // Start particle emitter on the client
   if (isGhost() && stateData.emitter)
      startImageEmitter(image,stateData);

   // Start spin thread
   if (image.spinThread) {
      switch (stateData.spin) {
       case ShapeBaseImageData::StateData::IgnoreSpin:
         image.shapeInstance->setTimeScale(image.spinThread, image.shapeInstance->getTimeScale(image.spinThread));
         break;
       case ShapeBaseImageData::StateData::NoSpin:
         image.shapeInstance->setTimeScale(image.spinThread,0);
         break;
       case ShapeBaseImageData::StateData::SpinUp:
         if (lastState.spin == ShapeBaseImageData::StateData::SpinDown)
            image.delayTime *= 1.0f - (lastDelay / stateData.timeoutValue);
         break;
       case ShapeBaseImageData::StateData::SpinDown:
         if (lastState.spin == ShapeBaseImageData::StateData::SpinUp)
            image.delayTime *= 1.0f - (lastDelay / stateData.timeoutValue);
         break;
       case ShapeBaseImageData::StateData::FullSpin:
         image.shapeInstance->setTimeScale(image.spinThread,1);
         break;
      }
   }

   // Script callback on server
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (stateData.script && stateData.script[0])
#else
   if (stateData.script && stateData.script[0] && !isGhost())
#endif
      scriptCallback(imageSlot,stateData.script);

   // If there is a zero timeout, and a timeout transition, then
   // go ahead and transition imediately.
   if (!image.delayTime)
   {
      if ((ns = stateData.transition.timeout) != -1)
      {
         setImageState(imageSlot,ns);
         return;
      }
   }
}


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

void ShapeBase::updateImageState(U32 imageSlot,F32 dt)
{
   if (!mMountedImageList[imageSlot].dataBlock)
      return;
   MountedImage& image = mMountedImageList[imageSlot];
   ShapeBaseImageData& imageData = *image.dataBlock;
   ShapeBaseImageData::StateData& stateData = *image.state;
   image.delayTime -= dt;

   // Energy management
   if (imageData.usesEnergy) {
      F32 newEnergy = getEnergyLevel() - stateData.energyDrain * dt;
      if (newEnergy < 0)
         newEnergy = 0;
      setEnergyLevel(newEnergy);

#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
      if (!isGhost()) 
#endif
		{
         bool ammo = newEnergy > imageData.minEnergy;
         if (ammo != image.ammo) {
            setMaskBits(ImageMaskN << imageSlot);
            image.ammo = ammo;
         }
      }
   }

   // Check for transitions. On some states we must wait for the
   // full timeout value before moving on.
   S32 ns;
   if (image.delayTime <= 0 || !stateData.waitForTimeout) {
      if ((ns = stateData.transition.loaded[image.loaded]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
      if ((ns = stateData.transition.ammo[image.ammo]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
      if ((ns = stateData.transition.target[image.target]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
      if ((ns = stateData.transition.wet[image.wet]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
      if ((ns = stateData.transition.trigger[image.triggerDown]) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
      if (image.delayTime <= 0 &&
          (ns = stateData.transition.timeout) != -1) {
         setImageState(imageSlot,ns);
         return;
      }
   }

   // Update the spinning thread timeScale
   if (image.spinThread) {
      float timeScale;

      switch (stateData.spin) {
         case ShapeBaseImageData::StateData::IgnoreSpin:
         case ShapeBaseImageData::StateData::NoSpin:
         case ShapeBaseImageData::StateData::FullSpin: {
            timeScale = 0;
            image.shapeInstance->setTimeScale(image.spinThread, image.shapeInstance->getTimeScale(image.spinThread));
            break;
         }

         case ShapeBaseImageData::StateData::SpinUp: {
            timeScale = 1.0f - image.delayTime / stateData.timeoutValue;
            image.shapeInstance->setTimeScale(image.spinThread,timeScale);
            break;
         }

         case ShapeBaseImageData::StateData::SpinDown: {
            timeScale = image.delayTime / stateData.timeoutValue;
            image.shapeInstance->setTimeScale(image.spinThread,timeScale);
            break;
         }
      }
   }
}


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

void ShapeBase::updateImageAnimation(U32 imageSlot, F32 dt)
{
   if (!mMountedImageList[imageSlot].dataBlock)
      return;
   MountedImage& image = mMountedImageList[imageSlot];

   // Advance animation threads
   if (image.ambientThread)
      image.shapeInstance->advanceTime(dt,image.ambientThread);
   if (image.animThread)
      image.shapeInstance->advanceTime(dt,image.animThread);
   if (image.spinThread)
      image.shapeInstance->advanceTime(dt,image.spinThread);
   if (image.flashThread)
      image.shapeInstance->advanceTime(dt,image.flashThread);

   // Update any playing sound.
   if (image.animSound)
      alxSourceMatrixF(image.animSound, &getRenderTransform());

   // Particle emission
   for (S32 i = 0; i < MaxImageEmitters; i++) {
      MountedImage::ImageEmitter& em = image.emitter[i];
      if (bool(em.emitter)) {
         if (em.time > 0) {
            em.time -= dt;

            MatrixF mat;
            getRenderImageTransform(imageSlot,em.node,&mat);
            Point3F pos,axis;
            mat.getColumn(3,&pos);
            mat.getColumn(1,&axis);
            em.emitter->emitParticles(pos,true,axis,getVelocity(),(U32) (dt * 1000));
         }
         else {
            em.emitter->deleteWhenEmpty();
            em.emitter = 0;
         }
      }
   }
}


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

void ShapeBase::startImageEmitter(MountedImage& image,ShapeBaseImageData::StateData& state)
{
   MountedImage::ImageEmitter* bem = 0;
   MountedImage::ImageEmitter* em = image.emitter;
   MountedImage::ImageEmitter* ee = &image.emitter[MaxImageEmitters];

   // If we are already emitting the same particles from the same
   // node, then simply extend the time.  Otherwise, find an empty
   // emitter slot, or grab the one with the least amount of time left.
   for (; em != ee; em++) {
      if (bool(em->emitter)) {
         if (state.emitter == em->emitter->getDataBlock() && state.emitterNode == em->node) {
            if (state.emitterTime > em->time)
               em->time = state.emitterTime;
            return;
         }
         if (!bem || (bool(bem->emitter) && bem->time > em->time))
            bem = em;
      }
      else
         bem = em;
   }

   bem->time = state.emitterTime;
   bem->node = state.emitterNode;
   bem->emitter = new ParticleEmitter;
   bem->emitter->onNewDataBlock(state.emitter);
   if( !bem->emitter->registerObject() )
      delete bem->emitter;
}


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

Light* ShapeBase::getImageLight(U32 imageSlot)
{
   MountedImage& image = mMountedImageList[imageSlot];
   if (!image.dataBlock)
      return 0;

   ShapeBaseImageData& imageData = *image.dataBlock;
   if (imageData.lightType == ShapeBaseImageData::NoLight)
      return 0;

   F32 intensity;
   F32 delta = Sim::getCurrentTime() - image.lightStart;
   switch (imageData.lightType) {
    case ShapeBaseImageData::ConstantLight:
      in

⌨️ 快捷键说明

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