1 /*
2 Copyright (C) 2007, 2010 - Bit-Blot
3 
4 This file is part of Aquaria.
5 
6 Aquaria is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15 See the 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 #ifndef __particles__
22 #define __particles__
23 
24 #include "Core.h"
25 #include "Quad.h"
26 
27 class Emitter;
28 class ParticleEffect;
29 
30 struct SpawnParticleData
31 {
32 	SpawnParticleData();
33 
34 	float randomScale1, randomScale2;
35 	float randomAlphaMod1, randomAlphaMod2;
36 	enum { NO_SPAWN = 999 };
37 
38 	enum SpawnArea { SPAWN_CIRCLE=0, SPAWN_LINE };
39 
40 	int pauseLevel;
41 	int flipH, flipV;
42 	SpawnArea spawnArea;
43 
44 	float avatarVelocity;
45 	float updateMultiplier;
46 
47 	InterpolatedVector velocityMagnitude;
48 	int randomParticleAngleRange;
49 	int randomVelocityRange;
50 
51 	float randomVelocityMagnitude;
52 	int randomRotationRange;
53 	InterpolatedVector initialVelocity, number, gravity;
54 	float randomSpawnRadius;
55 	Vector randomSpawnMod;
56 	int randomSpawnRadiusRange;
57 	bool didOne;
58 	int justOne;
59 
60 	int alphaModTimesVel;
61 
62 	int copyParentRotation, copyParentFlip;
63 	bool useSpawnRate;
64 	bool calculateVelocityToCenter;
65 	bool fadeAlphaWithLife, addAsChild;
66 	int width, height;
67 	InterpolatedVector scale, rotation, color, alpha, spawnOffset;
68 	float life;
69 	InterpolatedVector spawnRate;
70 	std::string texture;
71 	RenderObject::BlendTypes blendType;
72 	float counter;
73 	float spawnTimeOffset;
74 	bool spawnLocal;
75 	bool inheritColor;
76 	bool inheritAlpha;
77 
78 	float lastDTDifference;
79 	int groupRender;
80 	int influenced;
81 	std::string deathPrt;
82 
83 	int suckIndex, suckStr;
84 };
85 
86 struct Particle
87 {
ParticleParticle88 	Particle()
89 	{
90 		reset();
91 	}
resetParticle92 	void reset()
93 	{
94 		active = false;
95 		life = 1;
96 		emitter = 0;
97 		color.stop();
98 		scale.stop();
99 		rot.stop();
100 		alpha.stop();
101 		pos = Vector(0,0);
102 		vel = Vector(0,0);
103 		gvy = Vector(0,0);
104 		lpos = Vector(0,0);
105 		color = Vector(1,1,1);
106 		alpha = 1;
107 		scale = Vector(1,1);
108 		rot = Vector(0,0,0);
109 		emitter = 0;
110 		index = -1;
111 	}
112 	float life;
113 	bool active;
114 	Vector pos, vel, gvy, lpos;
115 	InterpolatedVector color, alpha, scale, rot;
116 	Emitter *emitter;
117 	int index;
118 };
119 
120 typedef std::vector<Particle> Particles;
121 
122 class Emitter : public Quad
123 {
124 public:
125 	Emitter(ParticleEffect *pe);
126 	void destroy();
127 	void addParticle(Particle *p);
128 	void removeParticle(Particle *p);
129 
130 	SpawnParticleData data;
131 
132 	void render();
133 
134 	void start();
135 	void stop();
136 
isEmpty()137 	bool isEmpty() const {return particles.empty();}
138 
139 
140 	Vector getSpawnPosition();
141 
142 	bool hasRot;
143 protected:
144 	Vector currentSpawn, lastSpawn;
145 	void onRender();
146 	void spawnParticle(float perc=1);
147 	void onUpdate(float dt);
148 
149 	ParticleEffect *pe;
150 
151 	typedef std::list<Particle*> Particles;
152 	Particles particles;
153 };
154 
155 class ParticleEffect : public RenderObject
156 {
157 public:
158 	ParticleEffect();
159 	void load(const std::string &name);
160 	void bankLoad(const std::string &name, const std::string &path);
161 	void start();
162 	void stop();
isRunning()163 	bool isRunning() const {return running;}
164 	void killParticleEffect();
165 	Emitter *addNewEmitter();
166 	void clearEmitters();
167 	void transfer(ParticleEffect *pe);
168 
169 	void setDie(bool v);
170 
171 	std::string name;
172 protected:
173 	bool die;
174 	bool waitForParticles;
175 
176 	void onUpdate(float dt);
177 	void onRender();
178 
179 	float effectLife, effectLifeCounter;
180 	bool running;
181 	typedef std::list<Emitter*> Emitters;
182 	Emitters emitters;
183 };
184 
185 struct ParticleInfluence
186 {
ParticleInfluenceParticleInfluence187 	ParticleInfluence(Vector pos, float spd, float size, bool pull)
188 		: pos(pos), spd(spd), size(size), pull(pull)
189 	{}
ParticleInfluenceParticleInfluence190 	ParticleInfluence() : size(0), spd(0), pull(false) {}
191 	Vector pos;
192 	float size;
193 	float spd;
194 	bool pull;
195 };
196 
197 class ParticleManager
198 {
199 public:
200 	ParticleManager(int size);
201 	void setSize(int size);
202 	void loadParticleBank(const std::string &bank1, const std::string &bank2);
203 	void clearParticleBank();
204 
205 	Particle *getFreeParticle(Emitter *emitter);
206 	int getSize();
207 
208 	void update(float dt);
209 
210 	void loadParticleEffectFromBank(const std::string &name, ParticleEffect *load);
211 	void updateParticle(Particle *p, float dt);
212 
213 	void clearInfluences();
214 	void addInfluence(ParticleInfluence inf);
215 	int (*collideFunction)(Vector pos);
216 	void (*specialFunction)(Particle *me);
217 
218 	void endParticle(Particle *p);
219 
220 	void setFree(int free);
221 
getFree()222 	int getFree() { return free; }
getNumActive()223 	int getNumActive() { return numActive; }
224 
225 	void setNumSuckPositions(int num);
226 	void setSuckPosition(int idx, const Vector &pos);
227 
228 	Vector *getSuckPosition(int idx);
229 
230 	static std::string particleBankPath;
231 
232 protected:
233 
234 
235 
236 	std::vector<Vector> suckPositions;
237 	int numActive;
238 	Particle* stomp();
239 
240 	void nextFree(int f=1);
241 	void prevFree(int f=1);
242 
243 	int oldFree;
244 
245 	typedef std::vector<ParticleInfluence> Influences;
246 	Influences influences;
247 
248 	int size, used, free, halfSize;
249 	Particles particles;
250 
251 
252 };
253 
254 extern ParticleManager *particleManager;
255 
256 #endif
257 
258