summaryrefslogtreecommitdiff
path: root/src/particle
diff options
context:
space:
mode:
Diffstat (limited to 'src/particle')
-rw-r--r--src/particle/particleengine.cpp234
-rw-r--r--src/particle/particleengine.h236
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;