diff options
-rw-r--r-- | src/particle/particleengine.cpp | 234 | ||||
-rw-r--r-- | src/particle/particleengine.h | 236 |
2 files changed, 10 insertions, 460 deletions
diff --git a/src/particle/particleengine.cpp b/src/particle/particleengine.cpp index 1a65b51d8..cb43f5059 100644 --- a/src/particle/particleengine.cpp +++ b/src/particle/particleengine.cpp @@ -56,28 +56,8 @@ bool ParticleEngine::enabled = true; const float ParticleEngine::PARTICLE_SKY = 800.0F; ParticleEngine::ParticleEngine() : - Actor(), - mAlpha(1.0F), - mLifetimeLeft(-1), - mLifetimePast(0), - mFadeOut(0), - mFadeIn(0), - mVelocity(), - mAlive(AliveStatus::ALIVE), - mChildEmitters(), mChildParticles(), - mDeathEffect(), - mGravity(0.0F), - mBounce(0.0F), - mAcceleration(0.0F), - mInvDieDistance(-1.0F), - mMomentum(1.0F), - mTarget(nullptr), - mRandomness(0), - mDeathEffectConditions(0x00), - mAutoDelete(true), - mAllowSizeAdjust(false), - mFollow(false) + mMap(nullptr) { ParticleEngine::particleCount++; } @@ -97,161 +77,13 @@ void ParticleEngine::setupEngine() restrict2 if (!ParticleEngine::emitterSkip) ParticleEngine::emitterSkip = 1; ParticleEngine::enabled = config.getBoolValue("particleeffects"); - disableAutoDelete(); logger->log1("Particle engine set up"); } -void ParticleEngine::draw(Graphics *restrict const, - const int, const int) const restrict2 -{ -} - -void ParticleEngine::updateSelf() restrict2 -{ - if (mLifetimeLeft == 0 && mAlive == AliveStatus::ALIVE) - mAlive = AliveStatus::DEAD_TIMEOUT; - - if (mAlive == AliveStatus::ALIVE) - { - // calculate particle movement - if (mMomentum != 1.0F) - mVelocity *= mMomentum; - - if (mTarget && mAcceleration != 0.0F) - { - Vector dist = mPos - mTarget->mPos; - dist.x *= SIN45; - float invHypotenuse; - - switch (ParticleEngine::fastPhysics) - { - case 1: - invHypotenuse = fastInvSqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); - break; - case 2: - if (!dist.x) - { - invHypotenuse = 0; - break; - } - - invHypotenuse = 2.0F / (static_cast<float>(fabs(dist.x)) - + static_cast<float>(fabs(dist.y)) - + static_cast<float>(fabs(dist.z))); - break; - default: - invHypotenuse = 1.0F / static_cast<float>(sqrt( - dist.x * dist.x + dist.y * dist.y + dist.z * dist.z)); - break; - } - - if (invHypotenuse) - { - if (mInvDieDistance > 0.0F && invHypotenuse > mInvDieDistance) - mAlive = AliveStatus::DEAD_IMPACT; - const float accFactor = invHypotenuse * mAcceleration; - mVelocity -= dist * accFactor; - } - } - - if (mRandomness > 0) - { - mVelocity.x += static_cast<float>((rand() % mRandomness - rand() - % mRandomness)) / 1000.0F; - mVelocity.y += static_cast<float>((rand() % mRandomness - rand() - % mRandomness)) / 1000.0F; - mVelocity.z += static_cast<float>((rand() % mRandomness - rand() - % mRandomness)) / 1000.0F; - } - - mVelocity.z -= mGravity; - - // Update position - mPos.x += mVelocity.x; - mPos.y += mVelocity.y * SIN45; - mPos.z += mVelocity.z * SIN45; - - // Update other stuff - if (mLifetimeLeft > 0) - mLifetimeLeft--; - - mLifetimePast++; - - if (mPos.z < 0.0F) - { - if (mBounce > 0.0F) - { - mPos.z *= -mBounce; - mVelocity *= mBounce; - mVelocity.z = -mVelocity.z; - } - else - { - mAlive = AliveStatus::DEAD_FLOOR; - } - } - else if (mPos.z > PARTICLE_SKY) - { - mAlive = AliveStatus::DEAD_SKY; - } - - // Update child emitters - if (ParticleEngine::emitterSkip && (mLifetimePast - 1) - % ParticleEngine::emitterSkip == 0) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - { - std::vector<Particle*> newParticles; - (*e)->createParticles(mLifetimePast, newParticles); - FOR_EACH (std::vector<Particle*>::const_iterator, - it, - newParticles) - { - Particle *const p = *it; - p->moveBy(mPos); - mChildParticles.push_back(p); - } - } - } - } - - // create death effect when the particle died - if (mAlive != AliveStatus::ALIVE && - mAlive != AliveStatus::DEAD_LONG_AGO) - { - if ((CAST_U32(mAlive) & mDeathEffectConditions) - > 0x00 && !mDeathEffect.empty()) - { - Particle *restrict const deathEffect = particleEngine->addEffect( - mDeathEffect, 0, 0); - if (deathEffect) - deathEffect->moveBy(mPos); - } - mAlive = AliveStatus::DEAD_LONG_AGO; - } -} - bool ParticleEngine::update() restrict2 { - if (!mMap) - return false; - - const Vector oldPos = mPos; - - updateSelf(); - - const Vector change = mPos - oldPos; - - if (mChildParticles.empty()) - { - if (mAlive != AliveStatus::ALIVE && - mAutoDelete) - { - return false; - } + if (mChildParticles.empty() || !mMap) return true; - } // Update child particles @@ -273,10 +105,6 @@ bool ParticleEngine::update() restrict2 ++p; continue; } - // move particle with its parent if desired - if (particle->mFollow) - particle->moveBy(change); - // update particle if (particle->update()) { @@ -288,32 +116,9 @@ bool ParticleEngine::update() restrict2 p = mChildParticles.erase(p); } } - if (mAlive != AliveStatus::ALIVE && - mChildParticles.empty() && - mAutoDelete) - { - return false; - } - return true; } -void ParticleEngine::moveBy(const Vector &restrict change) restrict2 -{ - mPos += change; - FOR_EACH (ParticleConstIterator, p, mChildParticles) - { - Particle *restrict const particle = *p; - if (particle->mFollow) - particle->moveBy(change); - } -} - -void ParticleEngine::moveTo(const float x, const float y) restrict2 -{ - moveTo(Vector(x, y, mPos.z)); -} - Particle *ParticleEngine::createChild() restrict2 { Particle *const newParticle = new Particle(); @@ -394,9 +199,9 @@ Particle *ParticleEngine::addEffect(const std::string &restrict effectChildNode, "position-y", 0)); const float offsetZ = static_cast<float>(XML::getFloatProperty( effectChildNode, "position-z", 0)); - const Vector position(mPos.x + static_cast<float>(pixelX) + offsetX, - mPos.y + static_cast<float>(pixelY) + offsetY, - mPos.z + offsetZ); + const Vector position(static_cast<float>(pixelX) + offsetX, + static_cast<float>(pixelY) + offsetY, + offsetZ); newParticle->moveTo(position); const int lifetime = XML::getProperty(effectChildNode, "lifetime", -1); @@ -522,37 +327,8 @@ Particle *ParticleEngine::addTextRiseFadeOutEffect(const std::string &restrict return newParticle; } -void ParticleEngine::adjustEmitterSize(const int w, const int h) restrict2 -{ - if (mAllowSizeAdjust) - { - FOR_EACH (EmitterConstIterator, e, mChildEmitters) - (*e)->adjustSize(w, h); - } -} - -void ParticleEngine::prepareToDie() restrict2 -{ - FOR_EACH (ParticleIterator, p, mChildParticles) - { - Particle *restrict const particle = *p; - if (!particle) - continue; - particle->prepareToDie(); - if (particle->isAlive() && - particle->mLifetimeLeft == -1 && - particle->mAutoDelete) - { - particle->kill(); - } - } -} - void ParticleEngine::clear() restrict2 { - delete_all(mChildEmitters); - mChildEmitters.clear(); - delete_all(mChildParticles); mChildParticles.clear(); } diff --git a/src/particle/particleengine.h b/src/particle/particleengine.h index 8916c0ac1..93688f777 100644 --- a/src/particle/particleengine.h +++ b/src/particle/particleengine.h @@ -23,14 +23,13 @@ #ifndef PARTICLE_PARTICLEENGINE_H #define PARTICLE_PARTICLEENGINE_H -#include "being/actor.h" - #include "enums/particle/alivestatus.h" #include "localconsts.h" class Color; class Font; +class Map; class Particle; class ParticleEmitter; @@ -41,7 +40,7 @@ typedef std::list<ParticleEmitter *> Emitters; typedef Emitters::iterator EmitterIterator; typedef Emitters::const_iterator EmitterConstIterator; -class ParticleEngine final : public Actor +class ParticleEngine final { public: static const float PARTICLE_SKY; // Maximum Z position of particles @@ -80,26 +79,6 @@ class ParticleEngine final : public Actor bool update() restrict2; /** - * Draws the particle image. - */ - void draw(Graphics *restrict const graphics, - const int offsetX, - const int offsetY) const restrict2 override - A_CONST A_NONNULL(2); - - /** - * Necessary for sorting with the other sprites. - */ - int getPixelY() const restrict2 override A_WARN_UNUSED - { return CAST_S32(mPos.y) - 16; } - - /** - * Necessary for sorting with the other sprites for sorting only. - */ - int getSortPixelY() const restrict2 override A_WARN_UNUSED - { return CAST_S32(mPos.y) - 16; } - - /** * Creates a blank particle as a child of the current particle * Useful for creating target particles */ @@ -133,219 +112,14 @@ class ParticleEngine final : public Actor const bool outline = false) restrict2 A_NONNULL(5, 6); - /** - * Adds an emitter to the particle. - */ - void addEmitter(ParticleEmitter *const emitter) restrict2 A_NONNULL(2) - { mChildEmitters.push_back(emitter); } - - /** - * Sets the position in 3 dimensional space in pixels relative to map. - */ - void moveTo(const Vector &restrict pos) restrict2 - { moveBy(pos - mPos); } - - /** - * Sets the position in 2 dimensional space in pixels relative to map. - */ - void moveTo(const float x, const float y) restrict2; - - /** - * Changes the particle position relative - */ - void moveBy(const Vector &restrict change) restrict2; - - /** - * Sets the time in game ticks until the particle is destroyed. - */ - void setLifetime(const int lifetime) restrict2 noexcept - { mLifetimeLeft = lifetime; mLifetimePast = 0; } - - /** - * Sets the age of the pixel in game ticks where the particle has - * faded in completely. - */ - void setFadeOut(const int fadeOut) restrict2 noexcept - { mFadeOut = fadeOut; } - - /** - * Sets the remaining particle lifetime where the particle starts to - * fade out. - */ - void setFadeIn(const int fadeIn) restrict2 noexcept - { mFadeIn = fadeIn; } - - /** - * Sets the current velocity in 3 dimensional space. - */ - void setVelocity(const float x, - const float y, - const float z) restrict2 noexcept - { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; } - - /** - * Sets the downward acceleration. - */ - void setGravity(const float gravity) restrict2 noexcept - { mGravity = gravity; } - - /** - * Sets the ammount of random vector changes - */ - void setRandomness(const int r) restrict2 noexcept - { mRandomness = r; } - - /** - * Sets the ammount of velocity particles retain after - * hitting the ground. - */ - void setBounce(const float bouncieness) restrict2 noexcept - { mBounce = bouncieness; } - - /** - * Sets the flag if the particle is supposed to be moved by its parent - */ - void setFollow(const bool follow) restrict2 noexcept - { mFollow = follow; } - - /** - * Gets the flag if the particle is supposed to be moved by its parent - */ - bool doesFollow() const restrict2 noexcept A_WARN_UNUSED - { return mFollow; } - - /** - * Makes the particle move toward another particle with a - * given acceleration and momentum - */ - void setDestination(Particle *restrict const target, - const float accel, - const float moment) restrict2 noexcept A_NONNULL(2) - { mTarget = target; mAcceleration = accel; mMomentum = moment; } - - /** - * Sets the distance in pixel the particle can come near the target - * particle before it is destroyed. Does only make sense after a target - * particle has been set using setDestination. - */ - void setDieDistance(const float dist) restrict2 - { mInvDieDistance = 1.0F / dist; } - - /** - * Changes the size of the emitters so that the effect fills a - * rectangle of this size - */ - void adjustEmitterSize(const int w, const int h) restrict2; - - void setAllowSizeAdjust(const bool adjust) restrict2 noexcept - { mAllowSizeAdjust = adjust; } - - bool isAlive() const restrict2 noexcept A_WARN_UNUSED - { return mAlive == AliveStatus::ALIVE; } - - void prepareToDie() restrict2; - - /** - * Determines whether the particle and its children are all dead - */ - bool isExtinct() const restrict2 noexcept A_WARN_UNUSED - { return !isAlive() && mChildParticles.empty(); } - - /** - * Manually marks the particle for deletion. - */ - void kill() restrict2 noexcept - { mAlive = AliveStatus::DEAD_OTHER; mAutoDelete = true; } - - /** - * After calling this function the particle will only request - * deletion when kill() is called - */ - void disableAutoDelete() restrict2 noexcept - { mAutoDelete = false; } + void setMap(Map *const map) + { mMap = map; } - /** We consider particles (at least for now) to be one layer-sprites */ - int getNumberOfLayers() const restrict2 override final - { return 1; } - - float getAlpha() const restrict2 override final - { return 1.0F; } - - void setAlpha(const float alpha A_UNUSED) restrict2 override - { } - - void setDeathEffect(const std::string &restrict effectFile, - const signed char conditions) restrict2 - { mDeathEffect = effectFile; mDeathEffectConditions = conditions; } - - protected: - void updateSelf() restrict2; - - // Opacity of the graphical representation of the particle - float mAlpha; - - // Lifetime left in game ticks - int mLifetimeLeft; - - // Age of the particle in game ticks - int mLifetimePast; - - // Lifetime in game ticks left where fading out begins - int mFadeOut; - - // Age in game ticks where fading in is finished - int mFadeIn; - - // Speed in pixels per game-tick. - Vector mVelocity; - - // Is the particle supposed to be drawn and updated? - AliveStatusT mAlive; private: - // List of child emitters. - Emitters mChildEmitters; - // List of particles controlled by this particle Particles mChildParticles; - // Particle effect file to be spawned when the particle dies - std::string mDeathEffect; - - // dynamic particle - // Downward acceleration in pixels per game-tick. - float mGravity; - - // How much the particle bounces off when hitting the ground - float mBounce; - - // Acceleration towards the target particle in pixels per game-tick - float mAcceleration; - - // Distance in pixels from the target particle that causes - // the destruction of the particle - float mInvDieDistance; - - // How much speed the particle retains after each game tick - float mMomentum; - - // The particle that attracts this particle - Particle *restrict mTarget; - - // Ammount of random vector change - int mRandomness; - - // Bitfield of death conditions which trigger spawning - // of the death particle - signed char mDeathEffectConditions; - - // May the particle request its deletion by the parent particle? - bool mAutoDelete; - - // Can the effect size be adjusted by the object props in the map file? - bool mAllowSizeAdjust; - - // is this particle moved when its parent particle moves? - bool mFollow; + Map *mMap; }; extern ParticleEngine *particleEngine; |