mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
646 lines
16 KiB
C++
646 lines
16 KiB
C++
// BSE_SegmentTemplate.cpp
|
|
//
|
|
|
|
|
|
#include "precompiled.h"
|
|
|
|
#include "BSE_Envelope.h"
|
|
#include "BSE_Particle.h"
|
|
#include "BSE.h"
|
|
|
|
void rvSegmentTemplate::CreateParticleTemplate(rvDeclEffect* effect, idParser* src, int particleType)
|
|
{
|
|
mParticleTemplate.Init();
|
|
mParticleTemplate.mType = particleType;
|
|
mParticleTemplate.SetParameterCounts();
|
|
mParticleTemplate.Parse(effect, src);
|
|
}
|
|
|
|
bool rvSegmentTemplate::GetSoundLooping()
|
|
{
|
|
if (mSoundShader != NULL) {
|
|
return ((unsigned int)mSoundShader->GetParms()->soundShaderFlags >> 5) & 1;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void rvSegmentTemplate::EvaluateTrailSegment(rvDeclEffect* et) {
|
|
if (mParticleTemplate.mTrailInfo->mTrailType && !mParticleTemplate.mTrailInfo->mTrailTypeName.IsEmpty())
|
|
{
|
|
// jmarshall - WindowName isn't defined and doesn't make sense here
|
|
// if (idStr::Cmp(v3->mTrailTypeName.data, (const char*)&WindowName))
|
|
// jmarshall end
|
|
{
|
|
mTrailSegmentIndex = et->GetTrailSegmentIndex(mParticleTemplate.mTrailInfo->mTrailTypeName);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool rvSegmentTemplate::GetSmoker()
|
|
{
|
|
return mParticleTemplate.mTrailInfo->mTrailType == 3;
|
|
}
|
|
|
|
bool rvSegmentTemplate::DetailCull() const
|
|
{
|
|
return (mDetail > 0.0f) && (cvarSystem->GetCVarFloat("bse_scale") < mDetail);
|
|
}
|
|
|
|
float rvSegmentTemplate::CalculateBounds(void)
|
|
{
|
|
switch (mSegType)
|
|
{
|
|
case SEG_EMITTER:
|
|
case SEG_SPAWNER:
|
|
case SEG_TRAIL: {
|
|
const float maxSize = mParticleTemplate.GetMaxSize();
|
|
const float maxDist = mParticleTemplate.GetFurthestDistance();
|
|
float maxLength = 0.0f;
|
|
const int particleType = mParticleTemplate.GetType();
|
|
if (particleType == PTYPE_LINE || particleType == PTYPE_ELECTRICITY) {
|
|
maxLength = mParticleTemplate.GetMaxLength();
|
|
}
|
|
return maxSize + maxDist + maxLength + mParticleTemplate.GetMaxOffset();
|
|
}
|
|
case SEG_LIGHT:
|
|
return mParticleTemplate.GetMaxSize();
|
|
default:
|
|
return 8.0f;
|
|
}
|
|
}
|
|
|
|
bool rvSegmentTemplate::Compare(const rvSegmentTemplate& a) const
|
|
{
|
|
if (mSegmentName.Icmp(a.mSegmentName) != 0) {
|
|
return false;
|
|
}
|
|
|
|
if (((mFlags ^ a.mFlags) & ~STFLAG_LOCKED) != 0) {
|
|
return false;
|
|
}
|
|
|
|
if (mSegType != a.mSegType) {
|
|
return false;
|
|
}
|
|
|
|
// Sound segments intentionally ignore local time ranges.
|
|
if (mSegType != SEG_SOUND) {
|
|
if (mLocalStartTime != a.mLocalStartTime || mLocalDuration != a.mLocalDuration) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (mScale != a.mScale || mDetail != a.mDetail || mAttenuation != a.mAttenuation) {
|
|
return false;
|
|
}
|
|
|
|
if (mDensity.y == 0.0f) {
|
|
if (mCount != a.mCount) {
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if (mDensity != a.mDensity || mParticleCap != a.mParticleCap) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (mTrailSegmentIndex != a.mTrailSegmentIndex || mNumEffects != a.mNumEffects) {
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < mNumEffects; ++i) {
|
|
if (mEffects[i] != a.mEffects[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (mSoundShader != a.mSoundShader || mSoundVolume != a.mSoundVolume || mFreqShift != a.mFreqShift) {
|
|
return false;
|
|
}
|
|
|
|
return mParticleTemplate == a.mParticleTemplate;
|
|
}
|
|
|
|
float rvSegmentTemplate::EvaluateCost(int activeParticles) const
|
|
{
|
|
float v4; // [esp+8h] [ebp-4h]
|
|
float activeParticlesa; // [esp+10h] [ebp+4h]
|
|
|
|
if ((mFlags & 1) == 0)
|
|
return 0.0;
|
|
v4 = rvSegmentTemplate::mSegmentBaseCosts[mSegType];
|
|
if (mParticleTemplate.mType)
|
|
{
|
|
activeParticlesa = (float)activeParticles;
|
|
v4 = mParticleTemplate.CostTrail(activeParticlesa) + v4;
|
|
if ((mParticleTemplate.mFlags & 0x200) != 0)
|
|
v4 = activeParticlesa * 80.0 + v4;
|
|
}
|
|
return v4;
|
|
}
|
|
|
|
rvParticleTemplate& rvParticleTemplate::operator=(const rvParticleTemplate& __that)
|
|
{
|
|
mFlags = __that.mFlags;
|
|
mTraceModelIndex = __that.mTraceModelIndex;
|
|
mType = __that.mType;
|
|
mMaterial = __that.mMaterial;
|
|
mModel = __that.mModel;
|
|
mEntityDefName = __that.mEntityDefName;
|
|
mGravity = __that.mGravity;
|
|
mDuration = __that.mDuration;
|
|
mCentre = __that.mCentre;
|
|
mTiling = __that.mTiling;
|
|
mBounce = __that.mBounce;
|
|
mPhysicsDistance = __that.mPhysicsDistance;
|
|
mWindDeviationAngle = __that.mWindDeviationAngle;
|
|
mVertexCount = __that.mVertexCount;
|
|
mIndexCount = __that.mIndexCount;
|
|
mTrailRepeat = __that.mTrailRepeat;
|
|
mNumSizeParms = __that.mNumSizeParms;
|
|
mNumRotateParms = __that.mNumRotateParms;
|
|
mNumFrames = __that.mNumFrames;
|
|
mTrailInfo = __that.mTrailInfo;
|
|
mElecInfo = __that.mElecInfo;
|
|
mpSpawnPosition = __that.mpSpawnPosition;
|
|
mpSpawnDirection = __that.mpSpawnDirection;
|
|
mpSpawnVelocity = __that.mpSpawnVelocity;
|
|
mpSpawnAcceleration = __that.mpSpawnAcceleration;
|
|
mpSpawnFriction = __that.mpSpawnFriction;
|
|
mpSpawnTint = __that.mpSpawnTint;
|
|
mpSpawnFade = __that.mpSpawnFade;
|
|
mpSpawnSize = __that.mpSpawnSize;
|
|
mpSpawnRotate = __that.mpSpawnRotate;
|
|
mpSpawnAngle = __that.mpSpawnAngle;
|
|
mpSpawnOffset = __that.mpSpawnOffset;
|
|
mpSpawnLength = __that.mpSpawnLength;
|
|
mpSpawnWindStrength = __that.mpSpawnWindStrength;
|
|
mpTintEnvelope = __that.mpTintEnvelope;
|
|
mpFadeEnvelope = __that.mpFadeEnvelope;
|
|
mpSizeEnvelope = __that.mpSizeEnvelope;
|
|
mpRotateEnvelope = __that.mpRotateEnvelope;
|
|
mpAngleEnvelope = __that.mpAngleEnvelope;
|
|
mpOffsetEnvelope = __that.mpOffsetEnvelope;
|
|
mpLengthEnvelope = __that.mpLengthEnvelope;
|
|
mpDeathTint = __that.mpDeathTint;
|
|
mpDeathFade = __that.mpDeathFade;
|
|
mpDeathSize = __that.mpDeathSize;
|
|
mpDeathRotate = __that.mpDeathRotate;
|
|
mpDeathAngle = __that.mpDeathAngle;
|
|
mpDeathOffset = __that.mpDeathOffset;
|
|
mpDeathLength = __that.mpDeathLength;
|
|
mNumImpactEffects = __that.mNumImpactEffects;
|
|
mImpactEffects[0] = __that.mImpactEffects[0];
|
|
mImpactEffects[1] = __that.mImpactEffects[1];
|
|
mImpactEffects[2] = __that.mImpactEffects[2];
|
|
mImpactEffects[3] = __that.mImpactEffects[3];
|
|
mNumTimeoutEffects = __that.mNumTimeoutEffects;
|
|
mTimeoutEffects[0] = __that.mTimeoutEffects[0];
|
|
mTimeoutEffects[1] = __that.mTimeoutEffects[1];
|
|
mTimeoutEffects[2] = __that.mTimeoutEffects[2];
|
|
mTimeoutEffects[3] = __that.mTimeoutEffects[3];
|
|
return *this;
|
|
}
|
|
|
|
void rvSegmentTemplate::Duplicate(const rvSegmentTemplate& copy)
|
|
{
|
|
mDeclEffect = copy.mDeclEffect;
|
|
mSegmentName = copy.mSegmentName;
|
|
mFlags = copy.mFlags;
|
|
mSegType = copy.mSegType;
|
|
mLocalStartTime = copy.mLocalStartTime;
|
|
mLocalDuration = copy.mLocalDuration;
|
|
mScale = copy.mScale;
|
|
mAttenuation = copy.mAttenuation;
|
|
mParticleCap = copy.mParticleCap;
|
|
mScale = copy.mScale;
|
|
mDetail = copy.mDetail;
|
|
mCount = copy.mCount;
|
|
mDensity = copy.mDensity;
|
|
mTrailSegmentIndex = copy.mTrailSegmentIndex;
|
|
mNumEffects = copy.mNumEffects;
|
|
mEffects[0] = copy.mEffects[0];
|
|
mEffects[1] = copy.mEffects[1];
|
|
mEffects[2] = copy.mEffects[2];
|
|
mEffects[3] = copy.mEffects[3];
|
|
mSoundShader = copy.mSoundShader;
|
|
mSoundVolume = copy.mSoundVolume;
|
|
mFreqShift = copy.mFreqShift;
|
|
mParticleTemplate.Duplicate(copy.mParticleTemplate);
|
|
mDecalAxis = copy.mDecalAxis;
|
|
}
|
|
|
|
void rvSegmentTemplate::Init(rvDeclEffect* decl)
|
|
{
|
|
mDeclEffect = decl;
|
|
mSegmentName = "";
|
|
mFlags = STFLAG_ENABLED;
|
|
mSegType = SEG_NONE;
|
|
mLocalStartTime.Zero();
|
|
mLocalDuration.Zero();
|
|
mAttenuation.Zero();
|
|
mParticleCap = 0.0f;
|
|
mScale = 1.0f;
|
|
mDetail = 0.0f;
|
|
mCount.Set(1.0f, 1.0f);
|
|
mDensity.Zero();
|
|
mTrailSegmentIndex = -1;
|
|
mNumEffects = 0;
|
|
for (int i = 0; i < BSE_NUM_SPAWNABLE; ++i) {
|
|
mEffects[i] = NULL;
|
|
}
|
|
mSoundShader = NULL;
|
|
mSoundVolume.Zero();
|
|
mFreqShift.Set(1.0f, 1.0f);
|
|
mDecalAxis = 0;
|
|
mParticleTemplate.Init();
|
|
}
|
|
|
|
|
|
void rvSegmentTemplate::SetMinDuration(rvDeclEffect* effect)
|
|
{
|
|
const idSoundShader* v2; // eax
|
|
float duration; // [esp+4h] [ebp-4h]
|
|
|
|
if ((mFlags & 0x10) == 0)
|
|
{
|
|
v2 = mSoundShader;
|
|
if (!v2 || (v2->GetParms()->soundShaderFlags & 0x20) == 0)
|
|
{
|
|
duration = mLocalDuration.x + mLocalStartTime.x;
|
|
effect->SetMinDuration(duration);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool rvSegmentTemplate::Finish(rvDeclEffect* effect)
|
|
{
|
|
rvParticleTemplate* v3; // edi
|
|
int v5; // ecx
|
|
float v6; // [esp+4h] [ebp-4h]
|
|
float v7; // [esp+4h] [ebp-4h]
|
|
float v8; // [esp+4h] [ebp-4h]
|
|
float v9; // [esp+4h] [ebp-4h]
|
|
float v10; // [esp+4h] [ebp-4h]
|
|
|
|
if (mLocalStartTime.y <= mLocalStartTime.x)
|
|
{
|
|
v6 = mLocalStartTime.x;
|
|
mLocalStartTime.x = mLocalStartTime.y;
|
|
mLocalStartTime.y = v6;
|
|
}
|
|
if (mLocalDuration.y <= mLocalDuration.x)
|
|
{
|
|
v7 = mLocalDuration.x;
|
|
mLocalDuration.x = mLocalDuration.y;
|
|
mLocalDuration.y = v7;
|
|
}
|
|
if (mCount.y <= mCount.x)
|
|
{
|
|
v8 = mCount.x;
|
|
mCount.x = mCount.y;
|
|
mCount.y = v8;
|
|
}
|
|
if (mDensity.y <= mDensity.x)
|
|
{
|
|
v9 = mDensity.x;
|
|
mDensity.x = mDensity.y;
|
|
mDensity.y = v9;
|
|
}
|
|
if (mAttenuation.y <= mAttenuation.x)
|
|
{
|
|
v10 = mAttenuation.x;
|
|
mAttenuation.x = mAttenuation.y;
|
|
mAttenuation.y = v10;
|
|
}
|
|
if (mParticleTemplate.mType)
|
|
{
|
|
v3 = &mParticleTemplate;
|
|
mParticleTemplate.Finish();
|
|
v3->mFlags &= 0xFFF7FFFF;
|
|
}
|
|
switch (mSegType)
|
|
{
|
|
case 2:
|
|
mFlags |= 4u;
|
|
if (mParticleTemplate.mType && (mFlags & 0x20) == 0)
|
|
goto LABEL_25;
|
|
return 0;
|
|
case 3:
|
|
mFlags |= 4u;
|
|
if (mParticleTemplate.mType)
|
|
goto LABEL_25;
|
|
return 0;
|
|
case 4:
|
|
mFlags |= 4u;
|
|
mLocalStartTime.y = 0.0;
|
|
mLocalStartTime.x = 0.0;
|
|
mLocalDuration.y = 0.0;
|
|
mLocalDuration.x = 0.0;
|
|
if (!mParticleTemplate.mType)
|
|
return 0;
|
|
mParticleTemplate.mFlags |= 0x80000u;
|
|
LABEL_25:
|
|
v5 = mParticleTemplate.mType;
|
|
if (v5 != PTYPE_NONE) {
|
|
mFlags |= STFLAG_HASPARTICLES;
|
|
}
|
|
if (v5 == 10)
|
|
mFlags = mFlags & 0xFFFFFFFB | 0x100;
|
|
if ((mFlags & 0x20) != 0
|
|
|| mParticleTemplate.mTrailInfo->mTrailType == 3
|
|
|| (mParticleTemplate.mFlags & 0x200) != 0
|
|
|| mParticleTemplate.mNumTimeoutEffects)
|
|
{
|
|
mFlags |= 0x2000u;
|
|
}
|
|
if (v5 == 7 || v5 == 6)
|
|
mFlags |= 0x2000u;
|
|
return 1;
|
|
case 5:
|
|
mFlags |= 0x10u;
|
|
goto LABEL_25;
|
|
case 6:
|
|
mFlags = mFlags & 0xFFFFFFFB | 0x100;
|
|
goto LABEL_25;
|
|
case SEG_SHAKE:
|
|
case SEG_TUNNEL:
|
|
case SEG_DOUBLEVISION:
|
|
if (mAttenuation.y > 0.0)
|
|
mFlags |= 0x40u;
|
|
goto LABEL_24;
|
|
default:
|
|
LABEL_24:
|
|
mFlags &= 0xFFFFFFFB;
|
|
goto LABEL_25;
|
|
}
|
|
}
|
|
|
|
|
|
void rvSegmentTemplate::operator=(const rvSegmentTemplate& copy)
|
|
{
|
|
this->mDeclEffect = copy.mDeclEffect;
|
|
this->mSegmentName = copy.mSegmentName;
|
|
this->mFlags = copy.mFlags;
|
|
this->mSegType = copy.mSegType;
|
|
this->mLocalStartTime = copy.mLocalStartTime;
|
|
this->mLocalDuration = copy.mLocalDuration;
|
|
this->mScale = copy.mScale;
|
|
this->mAttenuation = copy.mAttenuation;
|
|
this->mParticleCap = copy.mParticleCap;
|
|
this->mScale = copy.mScale;
|
|
this->mDetail = copy.mDetail;
|
|
this->mCount = copy.mCount;
|
|
this->mDensity = copy.mDensity;
|
|
this->mTrailSegmentIndex = copy.mTrailSegmentIndex;
|
|
this->mNumEffects = copy.mNumEffects;
|
|
this->mEffects[0] = copy.mEffects[0];
|
|
this->mEffects[1] = copy.mEffects[1];
|
|
this->mEffects[2] = copy.mEffects[2];
|
|
this->mEffects[3] = copy.mEffects[3];
|
|
this->mSoundShader = copy.mSoundShader;
|
|
this->mSoundVolume = copy.mSoundVolume;
|
|
this->mFreqShift = copy.mFreqShift;
|
|
this->mParticleTemplate = copy.mParticleTemplate;
|
|
this->mDecalAxis = copy.mDecalAxis;
|
|
}
|
|
|
|
void rvSegmentTemplate::SetMaxDuration(rvDeclEffect* effect)
|
|
{
|
|
rvSegmentTemplate* v2; // esi
|
|
rvDeclEffect* v3; // edi
|
|
float duration; // ST0C_4
|
|
float effecta; // [esp+14h] [ebp+4h]
|
|
|
|
v2 = this;
|
|
if (!(((unsigned int)this->mFlags >> 4) & 1))
|
|
{
|
|
v3 = effect;
|
|
duration = this->mLocalDuration.x + this->mLocalStartTime.x;
|
|
effect->SetMaxDuration(duration);
|
|
if (v2->mParticleTemplate.mType)
|
|
{
|
|
effecta = v2->mLocalDuration.x + v2->mLocalStartTime.x + v2->mParticleTemplate.mDuration.y;
|
|
v3->SetMaxDuration(effecta);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool rvSegmentTemplate::Parse(rvDeclEffect* effect, int segmentType, idParser* lexer) {
|
|
idToken token;
|
|
|
|
if (!lexer->ReadToken(&token))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (token != "{") {
|
|
mSegmentName = token;
|
|
}
|
|
else {
|
|
mSegmentName = va("unnamed%d", effect->GetNumSegmentTemplates());
|
|
lexer->UnreadToken(&token);
|
|
}
|
|
|
|
mSegType = segmentType;
|
|
|
|
if (!(lexer->ExpectTokenString("{") && lexer->ReadToken(&token))) {
|
|
return false;
|
|
}
|
|
|
|
while (token != "}")
|
|
{
|
|
if (token == "decalAxis")
|
|
{
|
|
mDecalAxis = lexer->ParseInt();
|
|
}
|
|
else if (token == "orientateIdentity")
|
|
{
|
|
mFlags |= STFLAG_ORIENTATE_IDENTITY;
|
|
}
|
|
else if (token == "useMaterialColor")
|
|
{
|
|
mFlags |= STFLAG_USEMATCOLOR;
|
|
}
|
|
else if (token == "depthsort")
|
|
{
|
|
mFlags |= STFLAG_DEPTH_SORT;
|
|
}
|
|
else if (!idStr::Icmp(token.c_str(), "inverseDrawOrder"))
|
|
{
|
|
mFlags |= STFLAG_INVERSE_DRAWORDER;
|
|
}
|
|
else if (token == "calcDuration")
|
|
{
|
|
mFlags |= STFLAG_CALCULATE_DURATION;
|
|
}
|
|
else if (token == "constant")
|
|
{
|
|
mFlags |= STFLAG_INFINITE_DURATION;
|
|
}
|
|
else if (token == "looping")
|
|
{
|
|
// Keep legacy token behavior aligned with constant duration segments.
|
|
mFlags |= STFLAG_INFINITE_DURATION;
|
|
}
|
|
else if (token == "locked")
|
|
{
|
|
mFlags |= STFLAG_LOCKED;
|
|
}
|
|
else if (!idStr::Icmp(token.c_str(), "temporary"))
|
|
{
|
|
mFlags |= STFLAG_TEMPORARY;
|
|
}
|
|
else if (token == "inverseAttenuateEmitter")
|
|
{
|
|
// Stock parser behavior enables attenuation when inverse attenuation is requested.
|
|
mFlags |= STFLAG_ATTENUATE_EMITTER | STFLAG_INVERSE_ATTENUATE;
|
|
}
|
|
else if (token == "attenuateEmitter")
|
|
{
|
|
mFlags |= STFLAG_ATTENUATE_EMITTER;
|
|
}
|
|
else if (token == "scale")
|
|
{
|
|
mScale = lexer->ParseFloat();
|
|
}
|
|
else if (token == "channel")
|
|
{
|
|
if (!lexer->ReadToken(&token)) {
|
|
return false;
|
|
}
|
|
}
|
|
else if (token == "effect")
|
|
{
|
|
if (!lexer->ReadToken(&token)) {
|
|
return false;
|
|
}
|
|
if (mNumEffects >= 4)
|
|
{
|
|
common->FatalError("Unable to add effect '%s' - too many effects\n", token.c_str());
|
|
}
|
|
else
|
|
{
|
|
mEffects[this->mNumEffects++] = declManager->FindEffect(token);
|
|
}
|
|
}
|
|
else if (idStr::Icmp(token.c_str(), "freqShift") == 0)
|
|
{
|
|
mFreqShift.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mFreqShift.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "attenuation")
|
|
{
|
|
mAttenuation.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mAttenuation.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "volume")
|
|
{
|
|
mSoundVolume.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mSoundVolume.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "soundShader")
|
|
{
|
|
if (!lexer->ReadToken(&token)) {
|
|
return false;
|
|
}
|
|
mSoundShader = (idSoundShader*)declManager->FindSound(token);
|
|
float effecta = 0.0f;
|
|
if (mSoundShader) {
|
|
effecta = 0.0f; // mSoundShader->GetTimeLength();
|
|
}
|
|
// Preserve a sane non-zero fallback for missing/streamed metadata.
|
|
if (effecta <= BSE_TIME_EPSILON) {
|
|
effecta = 1.0f;
|
|
}
|
|
mLocalDuration.x = effecta;
|
|
mLocalDuration.y = effecta;
|
|
}
|
|
else if (token == "detail")
|
|
{
|
|
mDetail = lexer->ParseFloat();
|
|
}
|
|
else if (token == "duration")
|
|
{
|
|
mLocalDuration.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mLocalDuration.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "start")
|
|
{
|
|
mLocalStartTime.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mLocalStartTime.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "density")
|
|
{
|
|
mDensity.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mDensity.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "count" || token == "rate")
|
|
{
|
|
mCount.x = lexer->ParseFloat();
|
|
lexer->ExpectTokenString(",");
|
|
mCount.y = lexer->ParseFloat();
|
|
}
|
|
else if (token == "particleCap")
|
|
{
|
|
mParticleCap = lexer->ParseFloat();
|
|
}
|
|
else if (token == "debris")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_DEBRIS);
|
|
}
|
|
else if (token == "orientedlinked")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_ORIENTEDLINKED);
|
|
}
|
|
else if (token == "linked")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_LINKED);
|
|
}
|
|
else if (token == "electricity")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_ELECTRICITY);
|
|
}
|
|
else if (token == "light")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_LIGHT);
|
|
}
|
|
else if (token == "model")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_MODEL);
|
|
}
|
|
else if (token == "decal")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_DECAL);
|
|
}
|
|
else if (token == "oriented")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_ORIENTED);
|
|
}
|
|
else if (token == "line")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_LINE);
|
|
}
|
|
else if (token == "sprite")
|
|
{
|
|
CreateParticleTemplate(effect, lexer, PTYPE_SPRITE);
|
|
}
|
|
else
|
|
{
|
|
common->Warning("^4BSE:^1 Invalid segment parameter '%s' (file: %s, line: %d)", token.c_str(), lexer->GetFileName(), lexer->GetLineNum());
|
|
}
|
|
|
|
if (!lexer->ReadToken(&token)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|