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

📄 weatherlightning.cpp

📁 五行MMORPG引擎系统V1.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine 
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "dgl/dgl.h"
#include "console/consoleTypes.h"
#include "math/mathIO.h"
#include "math/mRandom.h"
#include "sceneGraph/sceneState.h"
#include "audio/audioDataBlock.h"
#include "game/fx/weatherLightning.h"

IMPLEMENT_CO_CLIENTEVENT_V1(WeatherLightningStrikeEvent);
IMPLEMENT_CO_DATABLOCK_V1(WeatherLightningData);
IMPLEMENT_CO_NETOBJECT_V1(WeatherLightning);

MRandomLCG sgRandomGen;

S32 QSORT_CALLBACK cmpWLSounds(const void* p1, const void* p2)
{
   U32 i1 = *((const S32*)p1);
   U32 i2 = *((const S32*)p2);

   if (i1 < i2) {
      return 1;
   } else if (i1 > i2) {
      return -1;
   } else {
      return 0;
   }
}

S32 QSORT_CALLBACK cmpWLTextures(const void* t1, const void* t2)
{
   StringTableEntry ta = *(StringTableEntry*)t1;
   StringTableEntry tb = *(StringTableEntry*)t2;
   
   if(ta && ta[0] != '\0')
   {
      if(tb && tb[0] != '\0')
         return dStricmp(ta, tb);
      else
         return -1;
   }
   else
   {
      if(tb && tb[0] != '\0')
         return 1;
      else
         return 0;
   }
}

WeatherLightningStrikeEvent::WeatherLightningStrikeEvent()
{
   mLightning = NULL;
}

WeatherLightningStrikeEvent::~WeatherLightningStrikeEvent()
{
   
}

void WeatherLightningStrikeEvent::pack(NetConnection* con, BitStream* stream)
{
   if(!mLightning)
   {
      stream->writeFlag(false);
      return;
   }
   S32 ghostIndex = con->getGhostIndex(mLightning);
   if(ghostIndex == -1)
   {
      stream->writeFlag(false);
      return;
   }
   
   stream->writeFlag(true);
   stream->writeRangedU32(U32(ghostIndex), 0, GhostConnection::MaxGhostCount);
   stream->writeFloat(mStart.x, PositionalBits);
   stream->writeFloat(mStart.y, PositionalBits);
}

void WeatherLightningStrikeEvent::unpack(NetConnection* con, BitStream* stream)
{
   if(!stream->readFlag())
      return;
   S32 ghostIndex = stream->readRangedU32(0, GhostConnection::MaxGhostCount);
   mLightning = NULL;
   NetObject* pObject = con->resolveGhost(ghostIndex);
   if(pObject)
      mLightning = dynamic_cast<WeatherLightning*>(pObject);

   mStart.x = stream->readFloat(PositionalBits);
   mStart.y = stream->readFloat(PositionalBits);
}

void WeatherLightningStrikeEvent::process(NetConnection*)
{
   if (mLightning)
      mLightning->processEvent(this);
}

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

WeatherLightningData::WeatherLightningData()
{
   dMemset(strikeTextureNames, 0, sizeof(strikeTextureNames));
   dMemset(flashTextureNames,  0, sizeof(flashTextureNames));
   dMemset(fuzzyTextureNames,  0, sizeof(fuzzyTextureNames));
   
   dMemset(strikeTextures, 0, sizeof(strikeTextures));
   dMemset(flashTextures,  0, sizeof(flashTextures));
   dMemset(fuzzyTextures,  0, sizeof(fuzzyTextures));
   
   strikeSoundId = -1;
   strikeSound = NULL_AUDIOHANDLE;
   for(U32 i = 0; i < MaxSounds; i++)
   {
      thunderSoundIds[i] = -1;
      thunderSounds[i] = NULL_AUDIOHANDLE;
   }
}

WeatherLightningData::~WeatherLightningData()
{
   //
};

void WeatherLightningData::initPersistFields()
{
   Parent::initPersistFields();
   
   addField("strikeTextures", TypeFilename, Offset(strikeTextureNames, WeatherLightningData), MaxStrikeTextures);
   addField("flashTextures",  TypeFilename, Offset(flashTextureNames,  WeatherLightningData), MaxFlashTextures);
   addField("fuzzyTextures",  TypeFilename, Offset(fuzzyTextureNames,  WeatherLightningData), MaxFuzzyTextures);
   
   addField("strikeSound",    TypeAudioProfilePtr, Offset(strikeSound,   WeatherLightningData));
   addField("thunderSounds",  TypeAudioProfilePtr, Offset(thunderSounds, WeatherLightningData), MaxSounds);
}

bool WeatherLightningData::onAdd()
{
   if(!Parent::onAdd())
      return false;
   
   if(!strikeSound && strikeSoundId != -1)
   {
      if(Sim::findObject(strikeSoundId, strikeSound) == false)
         Con::errorf(ConsoleLogEntry::General, "WeatherLightningData::onAdd: Invalid packet, bad datablockId(sound: %d", strikeSound);
   }
   
   for(U32 i = 0; i < MaxSounds; i++)
   {
      if(!thunderSounds[i] && thunderSoundIds[i] != -1)
      {
         if(Sim::findObject(thunderSoundIds[i], thunderSounds[i]) == false)
            Con::errorf(ConsoleLogEntry::General, "WeahterLightningData::onAdd: Invalid packet, bad datablockId(sound: %d", thunderSounds[i]);
      }
   }
   
   return true;
}

bool WeatherLightningData::preload(bool server, char errorBuffer[256])
{
   if(Parent::preload(server, errorBuffer) == false)
      return false;
   
   dQsort(strikeTextureNames, MaxStrikeTextures, sizeof(StringTableEntry), cmpWLTextures);
   dQsort(flashTextureNames,  MaxFlashTextures,  sizeof(StringTableEntry), cmpWLTextures);
   dQsort(fuzzyTextureNames,  MaxFuzzyTextures,  sizeof(StringTableEntry), cmpWLTextures);

   if(!server) 
   {
      for(numStrikes = 0; numStrikes < MaxStrikeTextures; numStrikes++)
      {
         if(strikeTextureNames[numStrikes] && strikeTextureNames[numStrikes][0] != '\0')
            strikeTextures[numStrikes] = TextureHandle(strikeTextureNames[numStrikes], MeshTexture);
         else
            break;
      }     
      for(numFlashes = 0; numFlashes < MaxFlashTextures && flashTextureNames[numFlashes] != NULL; numFlashes++)
      {
         if(flashTextureNames[numFlashes] && flashTextureNames[numFlashes][0] != '\0')
            flashTextures[numFlashes] = TextureHandle(flashTextureNames[numFlashes], MeshTexture);
         else
            break;
      }
      for(numFuzzes = 0; numFuzzes < MaxFuzzyTextures && fuzzyTextureNames[numFuzzes] != NULL; numFuzzes++)
      {
         if(fuzzyTextureNames[numFuzzes] && fuzzyTextureNames[numFuzzes][0] != '\0')
            fuzzyTextures[numFuzzes] = TextureHandle(fuzzyTextureNames[numFuzzes], MeshTexture);
         else
            break;
      }
   }
   
   dQsort(thunderSounds, MaxSounds, sizeof(AudioProfile*), cmpWLSounds);
   for(numSounds = 0; numSounds < MaxSounds && thunderSounds[numSounds] != NULL_AUDIOHANDLE; numSounds++) {
      //
   }

   return true;
}

void WeatherLightningData::packData(BitStream* stream)
{
   Parent::packData(stream);

   U32 i;
   for (i = 0; i < MaxStrikeTextures; i++)
      stream->writeString(strikeTextureNames[i]);
   for(i = 0; i < MaxFlashTextures; i++)
      stream->writeString(flashTextureNames[i]);
   for(i = 0; i < MaxFuzzyTextures; i++)
      stream->writeString(fuzzyTextureNames[i]);
   
   if(stream->writeFlag(strikeSound != NULL_AUDIOHANDLE))
      stream->writeRangedU32(strikeSound->getId(), DataBlockObjectIdFirst,
                                                   DataBlockObjectIdLast);
   
   for(i = 0; i < MaxSounds; i++) 
   {
      if(stream->writeFlag(thunderSounds[i] != NULL_AUDIOHANDLE)) 
         stream->writeRangedU32(thunderSounds[i]->getId(), DataBlockObjectIdFirst,
                                                           DataBlockObjectIdLast);
   }
}

void WeatherLightningData::unpackData(BitStream* stream)
{
   Parent::unpackData(stream);

   U32 i;
   for(i = 0; i < MaxStrikeTextures; i++)
      strikeTextureNames[i] = stream->readSTString();
   for(i = 0; i < MaxFlashTextures; i++)
      flashTextureNames[i] = stream->readSTString();
   for(i = 0; i < MaxFuzzyTextures; i++)
      fuzzyTextureNames[i] = stream->readSTString();
     
   if(stream->readFlag())
      strikeSoundId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
   else
      strikeSoundId = -1;   
   
   for(i = 0; i < MaxSounds; i++)
   {
      if(stream->readFlag())
         thunderSoundIds[i] = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
      else
         thunderSoundIds[i] = -1;
   }
}

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

WeatherLightning::WeatherLightning()
{
   mNetFlags.set(Ghostable | ScopeAlways);
   mTypeMask |= StaticObjectType|EnvironmentObjectType;
   
   lastThink = 0;
   strikesPerMinute = 9;
   boltDeathAge = 1.5;
}

WeatherLightning::~WeatherLightning()
{
   //
}

void WeatherLightning::initPersistFields()
{
   Parent::initPersistFields();
   
   addNamedField(strikesPerMinute, TypeS32, WeatherLightning);
   addNamedField(boltDeathAge,     TypeF32, WeatherLightning);
}

bool WeatherLightning::onAdd()
{
   if(!Parent::onAdd())
      return false;
   
   mObjBox.min.set( -0.5, -0.5, -0.5 );
   mObjBox.max.set(  0.5,  0.5,  0.5 );
   resetWorldBox();
   
   addToScene();
   return true;
}

void WeatherLightning::onRemove()
{
   while(mActiveBolts.size())
   {
      WeatherLightningBolt* bolt = mActiveBolts[0];
      delete bolt;
      mActiveBolts.erase_fast(U32(0));
   }
   while(mSoundEvents.size())
      mSoundEvents.erase_fast(U32(0));
   
   removeFromScene();
   Parent::onRemove();
}

bool WeatherLightning::onNewDataBlock(GameBaseData* dptr)
{
   mDataBlock = dynamic_cast<WeatherLightningData*>(dptr);
   if(!mDataBlock || !Parent::onNewDataBlock(dptr))
      return false;

   scriptOnNewDataBlock();
   return true;
}

bool WeatherLightning::prepRenderImage(SceneState* state, const U32 stateKey, const U32, const bool)
{
   if(isLastState(state, stateKey))
      return false;
   setLastState(state, stateKey);

   // This should be sufficient for most objects that don't manage zones, and
   //  don't need to return a specialized RenderImage...
   if(state->isObjectRendered(this))
   {
      SceneRenderImage* image = new SceneRenderImage;
      image->obj = this;
      image->isTranslucent = true;
      image->sortType = SceneRenderImage::EndSort;
      state->insertRenderImage(image);
   }

   return false;
}

void WeatherLightningBolt::render(const Point3F &camPos)
{
   Point3F perpVec;
   Point3F lightUp = startPoint - endPoint;
   mCross(camPos - endPoint, lightUp, &perpVec);
   perpVec.normalize();
   
   Point3F frontVec;
   mCross(perpVec, lightUp, &frontVec);
   frontVec.normalize();
   
   glEnable(GL_DEPTH_TEST);
   glDepthMask(GL_FALSE);
   glDepthFunc(GL_LEQUAL);
   
   //
   // strike texture
   //

⌨️ 快捷键说明

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