1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2006  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#ifndef PARTICLE_H
23
#define PARTICLE_H
24
25
#include <list>
26
#include <string>
27
28
#include "guichanfwd.h"
29
#include "sprite.h"
30
#include "vector.h"
31
32
class Map;
33
class Particle;
34
class ParticleEmitter;
35
36
typedef std::list<Particle *> Particles;
37
typedef Particles::iterator ParticleIterator;
38
typedef std::list<ParticleEmitter *> Emitters;
39
typedef Emitters::iterator EmitterIterator;
40
41
/**
42
 * A particle spawned by a ParticleEmitter.
43
 */
44
class Particle : public Sprite
45
{
46
    public:
47
        static const float PARTICLE_SKY; /**< Maximum Z position of particles */
48
        static int fastPhysics;          /**< Mode of squareroot calculation */
49
        static int particleCount;        /**< Current number of particles */
50
        static int maxCount;             /**< Maximum number of particles */
51
        static int emitterSkip;          /**< Duration of pause between two emitter updates in ticks */
52
53
        /**
54
         * Constructor.
55
         *
56
         * @param map the map this particle will add itself to, may be NULL
57
         */
58
        Particle(Map *map);
59
60
        /**
61
         * Destructor.
62
         */
63
        ~Particle();
64
65
        /**
66
         * Deletes all child particles and emitters.
67
         */
68
        void clear();
69
70
        /**
71
         * Gives a particle the properties of an engine root particle and loads
72
         * the particle-related config settings.
73
         */
74
        void setupEngine();
75
76
        /**
77
         * Updates particle position, returns false when the particle should
78
         * be deleted.
79
         */
80
        virtual bool update();
81
82
        /**
83
         * Draws the particle image.
84
         */
85
        virtual void draw(Graphics *graphics, int offsetX, int offsetY) const;
86
87
        /**
88
         * Necessary for sorting with the other sprites.
89
         */
90
        virtual int getPixelY() const
91
        { return (int) (mPos.y + mPos.z) - 64; }
92
93
        /**
94
         * Sets the map the particle is on.
95
         */
96
        void setMap(Map *map);
97
98
        /**
99
         * Creates a child particle that hosts some emitters described in the
100
         * particleEffectFile.
101
         */
102
        Particle *addEffect(const std::string &particleEffectFile,
103
                            int pixelX, int pixelY, int rotation = 0);
104
105
        /**
106
         * Creates a standalone text particle.
107
         */
108
        Particle *addTextSplashEffect(const std::string &text, int x, int y,
109
                const gcn::Color *color, gcn::Font *font,
110
                bool outline = false);
111
112
        /**
113
         * Creates a standalone text particle.
114
         */
115
        Particle *addTextRiseFadeOutEffect(const std::string &text,
116
                int x, int y, const gcn::Color *color, gcn::Font *font,
117
                bool outline = false);
118
119
        /**
120
         * Adds an emitter to the particle.
121
         */
122
        void addEmitter (ParticleEmitter* emitter)
123
        { mChildEmitters.push_back(emitter); }
124
125
        /**
126
         * Sets the position in 3 dimensional space in pixels relative to map.
127
         */
128
        void moveTo(const Vector &pos)
129
        { moveBy (pos - mPos);}
130
131
        /**
132
         * Sets the position in 2 dimensional space in pixels relative to map.
133
         */
134
        void moveTo(float x, float y);
135
136
        /**
137
         * Returns the particle position.
138
         */
139
        const Vector& getPosition() const
140
        { return mPos; }
141
142
        /**
143
         * Changes the particle position relative
144
         */
145
        void moveBy (const Vector &change);
146
147
        /**
148
         * Sets the time in game ticks until the particle is destroyed.
149
         */
150
        void setLifetime(int lifetime)
151
        { mLifetimeLeft = lifetime; mLifetimePast = 0; }
152
153
        /**
154
         * Sets the age of the pixel in game ticks where the particle has
155
         * faded in completely.
156
         */
157
        void setFadeOut(int fadeOut)
158
        { mFadeOut = fadeOut; }
159
160
        /**
161
         * Sets the remaining particle lifetime where the particle starts to
162
         * fade out.
163
         */
164
        void setFadeIn(int fadeIn)
165
        { mFadeIn = fadeIn; }
166
167
        /**
168
         * Sets the alpha value of the particle
169
         */
170
        void setAlpha(float alpha)
171
        { mAlpha = alpha; }
172
173
        /**
174
         * Returns the current alpha opacity of the particle.
175
         */
176
        virtual float getAlpha() const
177
        { return mAlpha; }
178
179
        /**
180
         * Sets the sprite iterator of the particle on the current map to make
181
         * it easier to remove the particle from the map when it is destroyed.
182
         */
183
        void setSpriteIterator(std::list<Sprite*>::iterator spriteIterator)
184
        { mSpriteIterator = spriteIterator; }
185
186
        /**
187
         * Gets the sprite iterator of the particle on the current map.
188
         */
189
        std::list<Sprite*>::iterator
190
        getSpriteIterator() const
191
        { return mSpriteIterator; }
192
193
        /**
194
         * Sets the current velocity in 3 dimensional space.
195
         */
196
        void setVelocity(float x, float y, float z)
197
        { mVelocity.x = x; mVelocity.y = y; mVelocity.z = z; }
198
199
        /**
200
         * Sets the downward acceleration.
201
         */
202
        void setGravity(float gravity)
203
        { mGravity = gravity; }
204
205
        /**
206
         * Sets the ammount of random vector changes
207
         */
208
        void setRandomness(int r)
209
        { mRandomness = r; }
210
211
        /**
212
         * Sets the ammount of velocity particles retain after
213
         * hitting the ground.
214
         */
215
        void setBounce(float bouncieness)
216
        { mBounce = bouncieness; }
217
218
        /**
219
         * Sets the flag if the particle is supposed to be moved by its parent
220
         */
221
        void setFollow(bool follow)
222
        { mFollow = follow; }
223
224
        /**
225
         * Gets the flag if the particle is supposed to be moved by its parent
226
         */
227
        bool doesFollow()
228
        { return mFollow; }
229
230
        /**
231
         * Makes the particle move toward another particle with a
232
         * given acceleration and momentum
233
         */
234
        void setDestination(Particle *target, float accel, float moment)
235
        { mTarget = target; mAcceleration = accel; mMomentum = moment; }
236
237
        /**
238
         * Sets the distance in pixel the particle can come near the target
239
         * particle before it is destroyed. Does only make sense after a target
240
         * particle has been set using setDestination.
241
         */
242
        void setDieDistance(float dist)
243
        { mInvDieDistance = 1.0f / dist; }
244
245
        bool isAlive()
246
        { return mAlive; }
247
248
        /**
249
         * Determines whether the particle and its children are all dead
250
         */
251
        bool isExtinct()
252
        { return !isAlive() && mChildParticles.empty(); }
253
254
        /**
255
         * Manually marks the particle for deletion.
256
         */
257
        void kill()
258
        { mAlive = false; mAutoDelete = true; }
259
260
        /**
261
         * After calling this function the particle will only request
262
         * deletion when kill() is called
263
         */
264
        void disableAutoDelete()
265
        { mAutoDelete = false; }
266
267
        /** We consider particles (at least for now) to be one layer-sprites */
268
        virtual int getNumberOfLayers() const
269
        { return 1; }
270
271
    protected:
272
        bool mAlive;                /**< Is the particle supposed to be drawn and updated?*/
273
        Vector mPos;                /**< Position in pixels relative to map. */
274
        int mLifetimeLeft;          /**< Lifetime left in game ticks*/
275
        int mLifetimePast;          /**< Age of the particle in game ticks*/
276
        int mFadeOut;               /**< Lifetime in game ticks left where fading out begins*/
277
        int mFadeIn;                /**< Age in game ticks where fading in is finished*/
278
        float mAlpha;               /**< Opacity of the graphical representation of the particle */
279
280
        // generic properties
281
        bool mAutoDelete;           /**< May the particle request its deletion by the parent particle? */
282
        Map *mMap;                  /**< Map the particle is on. */
283
        std::list<Sprite*>::iterator mSpriteIterator;   /**< iterator of the particle on the current map */
284
        Emitters mChildEmitters;    /**< List of child emitters. */
285
        Particles mChildParticles;  /**< List of particles controlled by this particle */
286
287
        // dynamic particle
288
        Vector mVelocity;           /**< Speed in pixels per game-tick. */
289
        float mGravity;             /**< Downward acceleration in pixels per game-tick. */
290
        int mRandomness;            /**< Ammount of random vector change */
291
        float mBounce;              /**< How much the particle bounces off when hitting the ground */
292
        bool mFollow;               /**< is this particle moved when its parent particle moves? */
293
294
        // follow-point particles
295
        Particle *mTarget;          /**< The particle that attracts this particle*/
296
        float mAcceleration;        /**< Acceleration towards the target particle in pixels per game-tick*/
297
        float mInvDieDistance;      /**< Distance in pixels from the target particle that causes the destruction of the particle*/
298
        float mMomentum;            /**< How much speed the particle retains after each game tick*/
299
};
300
301
extern Particle *particleEngine;
302
303
#endif