From 3eeae12c498d1a4dbe969462d2ba841f77ee3ccb Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 2 Jan 2011 01:48:38 +0200 Subject: Initial commit. This code based on mana client http://www.gitorious.org/mana/mana and my private repository. --- src/particle.h | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 src/particle.h (limited to 'src/particle.h') diff --git a/src/particle.h b/src/particle.h new file mode 100644 index 000000000..a512e1f61 --- /dev/null +++ b/src/particle.h @@ -0,0 +1,331 @@ +/* + * The Mana Client + * Copyright (C) 2006-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * + * This file is part of The Mana Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef PARTICLE_H +#define PARTICLE_H + +#include "actor.h" +#include "guichanfwd.h" +#include "vector.h" + +#include +#include + +#ifdef __GNUC__ +#define _UNUSED_ __attribute__ ((unused)) +#else +#define _UNUSED_ +#endif + +class Map; +class Particle; +class ParticleEmitter; + +typedef std::list Particles; +typedef Particles::iterator ParticleIterator; +typedef std::list Emitters; +typedef Emitters::iterator EmitterIterator; + +/** + * A particle spawned by a ParticleEmitter. + */ +class Particle : public Actor +{ + public: + enum AliveStatus + { + ALIVE = 0, + DEAD_TIMEOUT = 1, + DEAD_FLOOR = 2, + DEAD_SKY = 4, + DEAD_IMPACT = 8, + DEAD_OTHER = 16, + DEAD_LONG_AGO = 128 + }; + static const float PARTICLE_SKY; /**< Maximum Z position + of particles */ + static int fastPhysics; /**< Mode of squareroot calculation */ + static int particleCount; /**< Current number of particles */ + static int maxCount; /**< Maximum number of particles */ + static int emitterSkip; /**< Duration of pause between two + emitter updates in ticks */ + static bool enabled; /**< true when non-crucial particle effects + are disabled */ + + /** + * Constructor. + * + * @param map the map this particle will add itself to, may be NULL + */ + Particle(Map *map); + + /** + * Destructor. + */ + ~Particle(); + + /** + * Deletes all child particles and emitters. + */ + void clear(); + + /** + * Gives a particle the properties of an engine root particle and loads + * the particle-related config settings. + */ + void setupEngine(); + + /** + * Updates particle position, returns false when the particle should + * be deleted. + */ + virtual bool update(); + + /** + * Draws the particle image. + */ + virtual bool draw(Graphics *graphics, int offsetX, int offsetY) const; + + /** + * Necessary for sorting with the other sprites. + */ + virtual int getPixelY() const + { return static_cast(mPos.y + mPos.z) - 64; } + + /** + * Creates a blank particle as a child of the current particle + * Useful for creating target particles + */ + Particle *createChild(); + + /** + * Creates a child particle that hosts some emitters described in the + * particleEffectFile. + */ + Particle *addEffect(const std::string &particleEffectFile, + int pixelX, int pixelY, int rotation = 0); + + /** + * Creates a standalone text particle. + */ + Particle *addTextSplashEffect(const std::string &text, int x, int y, + const gcn::Color *color, gcn::Font *font, + bool outline = false); + + /** + * Creates a standalone text particle. + */ + Particle *addTextRiseFadeOutEffect(const std::string &text, + int x, int y, + const gcn::Color *color, + gcn::Font *font, + bool outline = false); + + /** + * Adds an emitter to the particle. + */ + void addEmitter (ParticleEmitter* emitter) + { mChildEmitters.push_back(emitter); } + + /** + * Sets the position in 3 dimensional space in pixels relative to map. + */ + void moveTo(const Vector &pos) + { moveBy (pos - mPos); } + + /** + * Sets the position in 2 dimensional space in pixels relative to map. + */ + void moveTo(float x, float y); + + /** + * Changes the particle position relative + */ + void moveBy (const Vector &change); + + /** + * Sets the time in game ticks until the particle is destroyed. + */ + void setLifetime(int lifetime) + { mLifetimeLeft = lifetime; mLifetimePast = 0; } + + /** + * Sets the age of the pixel in game ticks where the particle has + * faded in completely. + */ + void setFadeOut(int fadeOut) + { mFadeOut = fadeOut; } + + /** + * Sets the remaining particle lifetime where the particle starts to + * fade out. + */ + void setFadeIn(int fadeIn) + { mFadeIn = fadeIn; } + + /** + * Sets the current velocity in 3 dimensional space. + */ + void setVelocity(float x, float y, float z) + { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; } + + /** + * Sets the downward acceleration. + */ + void setGravity(float gravity) + { mGravity = gravity; } + + /** + * Sets the ammount of random vector changes + */ + void setRandomness(int r) + { mRandomness = r; } + + /** + * Sets the ammount of velocity particles retain after + * hitting the ground. + */ + void setBounce(float bouncieness) + { mBounce = bouncieness; } + + /** + * Sets the flag if the particle is supposed to be moved by its parent + */ + void setFollow(bool follow) + { mFollow = follow; } + + /** + * Gets the flag if the particle is supposed to be moved by its parent + */ + bool doesFollow() + { return mFollow; } + + /** + * Makes the particle move toward another particle with a + * given acceleration and momentum + */ + void setDestination(Particle *target, float accel, float moment) + { 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(float dist) + { mInvDieDistance = 1.0f / dist; } + + /** + * Changes the size of the emitters so that the effect fills a + * rectangle of this size + */ + void adjustEmitterSize(int w, int h); + + void setAllowSizeAdjust(bool adjust) + { mAllowSizeAdjust = adjust; } + + bool isAlive() const + { return mAlive == ALIVE; } + + /** + * Determines whether the particle and its children are all dead + */ + bool isExtinct() const + { return !isAlive() && mChildParticles.empty(); } + + /** + * Manually marks the particle for deletion. + */ + void kill() + { mAlive = DEAD_OTHER; mAutoDelete = true; } + + /** + * After calling this function the particle will only request + * deletion when kill() is called + */ + void disableAutoDelete() + { mAutoDelete = false; } + + /** We consider particles (at least for now) to be one layer-sprites */ + virtual int getNumberOfLayers() const + { return 1; } + + virtual float getAlpha() const + { return 1.0f; } + + virtual void setAlpha(float alpha _UNUSED_) {} + + virtual void setDeathEffect(const std::string &effectFile, + char conditions) + { mDeathEffect = effectFile; mDeathEffectConditions = conditions; } + + protected: + float mAlpha; /**< Opacity of the graphical + representation of the particle */ + int mLifetimeLeft; /**< Lifetime left in game ticks*/ + int mLifetimePast; /**< Age of the particle in game ticks*/ + int mFadeOut; /**< Lifetime in game ticks left where + fading out begins*/ + int mFadeIn; /**< Age in game ticks where fading in is + finished*/ + Vector mVelocity; /**< Speed in pixels per game-tick. */ + + private: + AliveStatus mAlive; /**< Is the particle supposed to be + drawn and updated?*/ + // generic properties + bool mAutoDelete; /**< May the particle request its deletion + by the parent particle? */ + Emitters mChildEmitters; /**< List of child emitters. */ + Particles mChildParticles; /**< List of particles controlled by this + particle */ + bool mAllowSizeAdjust; /**< Can the effect size be adjusted by + the object props in the map file? */ + std::string mDeathEffect; /**< Particle effect file to be spawned + when the particle dies */ + char mDeathEffectConditions; /**< Bitfield of death conditions which + trigger spawning of the death + particle */ + + // dynamic particle + float mGravity; /**< Downward acceleration in pixels per + game-tick. */ + int mRandomness; /**< Ammount of random vector change */ + float mBounce; /**< How much the particle bounces off when + hitting the ground */ + bool mFollow; /**< is this particle moved when its parent + particle moves? */ + + // follow-point particles + Particle *mTarget; /**< The particle that attracts + this particle*/ + float mAcceleration; /**< Acceleration towards the target + particle in pixels per game-tick*/ + float mInvDieDistance; /**< Distance in pixels from the target + particle that causes the destruction + of the particle*/ + float mMomentum; /**< How much speed the particle retains + after each game tick*/ +}; + +extern Particle *particleEngine; + +#endif -- cgit v1.2.3-60-g2f50