diff options
Diffstat (limited to 'src/particle.cpp')
-rw-r--r-- | src/particle.cpp | 117 |
1 files changed, 81 insertions, 36 deletions
diff --git a/src/particle.cpp b/src/particle.cpp index 0c4a7d7e..4b8833eb 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -24,6 +24,7 @@ #include "animationparticle.h" #include "configuration.h" +#include "resources/dye.h" #include "imageparticle.h" #include "log.h" #include "map.h" @@ -56,15 +57,15 @@ bool Particle::enabled = true; const float Particle::PARTICLE_SKY = 800.0f; Particle::Particle(Map *map): - mAlive(true), + mAlpha(1.0f), mLifetimeLeft(-1), mLifetimePast(0), mFadeOut(0), mFadeIn(0), - mAlpha(1.0f), + mAlive(ALIVE), mAutoDelete(true), - mMap(map), mAllowSizeAdjust(false), + mDeathEffectConditions(0x00), mGravity(0.0f), mRandomness(0), mBounce(0.0f), @@ -74,33 +75,31 @@ Particle::Particle(Map *map): mInvDieDistance(-1.0f), mMomentum(1.0f) { + setMap(map); Particle::particleCount++; - if (mMap) - setSpriteIterator(mMap->addSprite(this)); } Particle::~Particle() { - // Remove from map sprite list - if (mMap) - mMap->removeSprite(mSpriteIterator); // Delete child emitters and child particles clear(); + //update particle count Particle::particleCount--; } void Particle::setupEngine() { - Particle::maxCount = (int)config.getValue("particleMaxCount", 3000); - Particle::fastPhysics = (int)config.getValue("particleFastPhysics", 0); - Particle::emitterSkip = (int)config.getValue("particleEmitterSkip", 1) + 1; - Particle::enabled = (bool)config.getValue("particleeffects", true); + Particle::maxCount = config.getIntValue("particleMaxCount"); + Particle::fastPhysics = config.getIntValue("particleFastPhysics"); + Particle::emitterSkip = config.getIntValue("particleEmitterSkip") + 1; + Particle::enabled = config.getBoolValue("particleeffects"); disableAutoDelete(); logger->log("Particle engine set up"); } -void Particle::draw(Graphics *, int, int) const +bool Particle::draw(Graphics *, int, int) const { + return false; } bool Particle::update() @@ -108,12 +107,12 @@ bool Particle::update() if (!mMap) return false; - if (mLifetimeLeft == 0) - mAlive = false; + if (mLifetimeLeft == 0 && mAlive == ALIVE) + mAlive = DEAD_TIMEOUT; Vector oldPos = mPos; - if (mAlive) + if (mAlive == ALIVE) { //calculate particle movement if (mMomentum != 1.0f) @@ -147,7 +146,7 @@ bool Particle::update() { if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance) { - mAlive = false; + mAlive = DEAD_IMPACT; } float accFactor = invHypotenuse * mAcceleration; mVelocity -= dist * accFactor; @@ -175,7 +174,7 @@ bool Particle::update() } mLifetimePast++; - if (mPos.z > PARTICLE_SKY || mPos.z < 0.0f) + if (mPos.z < 0.0f) { if (mBounce > 0.0f) { @@ -185,9 +184,13 @@ bool Particle::update() } else { - mAlive = false; + mAlive = DEAD_FLOOR; } } + else if (mPos.z > PARTICLE_SKY) + { + mAlive = DEAD_SKY; + } // Update child emitters if ((mLifetimePast-1)%Particle::emitterSkip == 0) @@ -206,6 +209,17 @@ bool Particle::update() } } + // create death effect when the particle died + if (mAlive != ALIVE && mAlive != DEAD_LONG_AGO) + { + if ((mAlive & mDeathEffectConditions) > 0x00 && !mDeathEffect.empty()) + { + Particle* deathEffect = particleEngine->addEffect(mDeathEffect, 0, 0); + deathEffect->moveBy(mPos); + } + mAlive = DEAD_LONG_AGO; + } + Vector change = mPos - oldPos; // Update child particles @@ -229,7 +243,7 @@ bool Particle::update() p = mChildParticles.erase(p); } } - if (!mAlive && mChildParticles.empty() && mAutoDelete) + if (mAlive != ALIVE && mChildParticles.empty() && mAutoDelete) { return false; } @@ -267,7 +281,12 @@ Particle *Particle::addEffect(const std::string &particleEffectFile, { Particle *newParticle = NULL; - XML::Document doc(particleEffectFile); + std::string::size_type pos = particleEffectFile.find('|'); + std::string dyePalettes; + if (pos != std::string::npos) + dyePalettes = particleEffectFile.substr(pos + 1); + + XML::Document doc(particleEffectFile.substr(0, pos)); xmlNodePtr rootNode = doc.rootNode(); if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect")) @@ -291,18 +310,20 @@ Particle *Particle::addEffect(const std::string &particleEffectFile, // Animation if ((node = XML::findFirstChildByName(effectChildNode, "animation"))) { - newParticle = new AnimationParticle(mMap, node); + newParticle = new AnimationParticle(mMap, node, dyePalettes); } // Rotational else if ((node = XML::findFirstChildByName(effectChildNode, "rotation"))) { - newParticle = new RotationalParticle(mMap, node); + newParticle = new RotationalParticle(mMap, node, dyePalettes); } // Image else if ((node = XML::findFirstChildByName(effectChildNode, "image"))) { - Image *img= resman->getImage((const char*) - node->xmlChildrenNode->content); + std::string imageSrc = (const char*)node->xmlChildrenNode->content; + if (!imageSrc.empty() && !dyePalettes.empty()) + Dye::instantiate(imageSrc, dyePalettes); + Image *img= resman->getImage(imageSrc); newParticle = new ImageParticle(mMap, img); } @@ -329,13 +350,39 @@ Particle *Particle::addEffect(const std::string &particleEffectFile, // Look for additional emitters for this particle for_each_xml_child_node(emitterNode, effectChildNode) { - if (!xmlStrEqual(emitterNode->name, BAD_CAST "emitter")) - continue; - - ParticleEmitter *newEmitter; - newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, - rotation); - newParticle->addEmitter(newEmitter); + if (xmlStrEqual(emitterNode->name, BAD_CAST "emitter")) + { + ParticleEmitter *newEmitter; + newEmitter = new ParticleEmitter(emitterNode, newParticle, mMap, + rotation, dyePalettes); + newParticle->addEmitter(newEmitter); + } + else if (xmlStrEqual(emitterNode->name, BAD_CAST "deatheffect")) + { + std::string deathEffect = (const char*)emitterNode->xmlChildrenNode->content; + char deathEffectConditions = 0x00; + if (XML::getBoolProperty(emitterNode, "on-floor", true)) + { + deathEffectConditions += Particle::DEAD_FLOOR; + } + if (XML::getBoolProperty(emitterNode, "on-sky", true)) + { + deathEffectConditions += Particle::DEAD_SKY; + } + if (XML::getBoolProperty(emitterNode, "on-other", false)) + { + deathEffectConditions += Particle::DEAD_OTHER; + } + if (XML::getBoolProperty(emitterNode, "on-impact", true)) + { + deathEffectConditions += Particle::DEAD_IMPACT; + } + if (XML::getBoolProperty(emitterNode, "on-timeout", true)) + { + deathEffectConditions += Particle::DEAD_TIMEOUT; + } + newParticle->setDeathEffect(deathEffect, deathEffectConditions); + } } mChildParticles.push_back(newParticle); @@ -406,11 +453,9 @@ float Particle::getCurrentAlpha() const return alpha; } -void Particle::setMap(Map *map) +int Particle::getDrawOrder() const { - mMap = map; - if (mMap) - setSpriteIterator(mMap->addSprite(this)); + return (int)(mPos.y) - 16; } void Particle::clear() |