📄 weatherlightning.cpp
字号:
//-----------------------------------------------------------------------------
// 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 + -