1 /*
2 Copyright (C) 2004-2011 Parallel Realities
3 Copyright (C) 2011-2015 Perpendicular Dimensions
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14 See the GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 */
21 
22 #include "particles.h"
23 
addWindParticles()24 void addWindParticles()
25 {
26 	int c;
27 	float x, y, dx, dy;
28 
29 
30 	for (int i = 0 ; i < 50 ; i++)
31 	{
32 		if (player.x < 320)
33 		{
34 			x = Math::rrand(-100, 700);
35 		}
36 		else
37 		{
38 			x = player.x + Math::rrand(-450, 450);
39 		}
40 
41 		c = Math::prand() % 4;
42 		switch (c)
43 		{
44 			case 0: c = graphics.white; break;
45 			case 1: c = graphics.lightGrey; break;
46 			case 2: c = graphics.grey; break;
47 			case 3: c = graphics.darkGrey; break;
48 		}
49 
50 		y = player.y + Math::rrand(-450, 450);
51 		dx = Math::rrand(1, 100) * map.windPower;
52 		dx /= 100;
53 		dy = Math::rrand(1, 10); dy /= 10;
54 		map.addParticle(x, y, dx, dy, 120, c, NULL, PAR_WEIGHTLESS);
55 	}
56 }
57 
addColorParticles(float x,float y,int amount,int color)58 void addColorParticles(float x, float y, int amount, int color)
59 {
60 	int c = color;
61 	float dx, dy;
62 
63 	for (int i = 0 ; i < amount ; i++)
64 	{
65 		if (color == -1)
66 			c = Math::prand() % 5;
67 
68 		switch (c)
69 		{
70 			case 0: c = graphics.white; break;
71 			case 1: c = graphics.grey; break;
72 			case 2: c = graphics.blue; break;
73 			case 3: c = graphics.cyan; break;
74 			case 4: c = graphics.red; break;
75 		}
76 
77 		dx = Math::rrand(-30, 30); dx /= 30;
78 		dy = Math::rrand(-30, 30); dy /= 30;
79 		map.addParticle(x, y, dx, dy, Math::rrand(5, 30), c, NULL, 0);
80 	}
81 }
82 
addFireTrailParticle(float x,float y)83 void addFireTrailParticle(float x, float y)
84 {
85 	map.addParticle(x, y, 0, 0, 12, graphics.red, graphics.getSprite("SmallExplosion", true), PAR_WEIGHTLESS);
86 }
87 
addFireParticles(float x,float y,int amount)88 void addFireParticles(float x, float y, int amount)
89 {
90 	for (int i = 0 ; i < amount ; i++)
91 	{
92 		map.addParticle(x + Math::rrand(-2, 2), y + Math::rrand(-2, 2), 0, 1, Math::rrand(5, 30), graphics.red, graphics.getSprite("Explosion", true), PAR_COLLIDES);
93 	}
94 }
95 
addBubble(float x,float y)96 void addBubble(float x, float y)
97 {
98 	if ((Math::prand() % 50) == 0)
99 	{
100 		map.addParticle(x + Math::prand() % BRICKSIZE, y + 19, 0, Math::rrand(-3, -1), Math::rrand(30, 90), graphics.red, graphics.getSprite("Bubble", true), PAR_COLLIDES | PAR_WEIGHTLESS | PAR_LIQUID);
101 	}
102 }
103 
throwStalagParticles(float x,float y)104 void throwStalagParticles(float x, float y)
105 {
106 	Sprite *stalagPiece = graphics.getSprite("StalagPiece", true);
107 
108 	int amount = Math::rrand(3, 6);
109 
110 	for (int i = 0 ; i < amount ; i++)
111 	{
112 		map.addParticle(x, y, Math::rrand(-2, 2), Math::rrand(-3, -1), Math::rrand(5, 30), graphics.red, stalagPiece, 0);
113 	}
114 }
115 
throwBrickParticles(float x,float y)116 void throwBrickParticles(float x, float y)
117 {
118 	int amount = Math::rrand(4, 8);
119 
120 	Sprite *wallPiece = graphics.getSprite("WallPiece", true);
121 
122 	for (int i = 0 ; i < amount ; i++)
123 	{
124 		map.addParticle(x, y, Math::rrand(-2, 2), Math::rrand(-4, -1), Math::rrand(5, 30), graphics.red, wallPiece, 0);
125 	}
126 }
127 
addTeleportParticles(float x,float y,int amount,int soundToPlay)128 void addTeleportParticles(float x, float y, int amount, int soundToPlay)
129 {
130 	Sprite *teleportStar = graphics.getSprite("TeleportStar", true);
131 	float dx, dy;
132 
133 	for (int i = 0 ; i < amount ; i++)
134 	{
135 		dx = Math::rrand(-30, 30); dx /= 20;
136 		dy = Math::rrand(-30, 30); dy /= 20;
137 		map.addParticle(x, y, dx, dy, Math::rrand(30, 60), graphics.red, teleportStar, PAR_WEIGHTLESS);
138 	}
139 
140 	if (soundToPlay != -1)
141 	{
142 		audio.playSound(soundToPlay, CH_SPAWN, x);
143 	}
144 }
145 
doParticles()146 void doParticles()
147 {
148 	Particle *particle = (Particle*)map.particleList.getHead();
149 	Particle *previous = particle;
150 
151 	int x, y;
152 
153 	while (particle->next != NULL)
154 	{
155 		particle = (Particle*)particle->next;
156 
157 		x = (int)(particle->x - engine.playerPosX);
158 		y = (int)(particle->y - engine.playerPosY);
159 
160 		if (particle->sprite == NULL)
161 		{
162 			graphics.lock(graphics.screen);
163 
164 			graphics.putPixel(x, y, particle->color, graphics.screen);
165 
166 			graphics.unlock(graphics.screen);
167 		}
168 		else
169 		{
170 			graphics.blit(particle->getFrame(), x, y, graphics.screen, false);
171 		}
172 
173 		particle->health--;
174 
175 		particle->move();
176 
177 		if (!(particle->flags & PAR_WEIGHTLESS))
178 		{
179 			particle->dy += 0.1;
180 		}
181 
182 		x = (int)particle->x >> BRICKSHIFT;
183 		y = (int)particle->y >> BRICKSHIFT;
184 
185 		if (particle->flags & PAR_COLLIDES)
186 		{
187 			if (map.isSolid(x, y))
188 			{
189 				particle->health = 0;
190 			}
191 		}
192 
193 		if (particle->flags & PAR_LIQUID)
194 		{
195 			if (!map.isLiquid(x, y))
196 			{
197 				particle->health = 0;
198 			}
199 		}
200 
201 		if (particle->health > 0)
202 		{
203 			previous = particle;
204 		}
205 		else
206 		{
207 			map.particleList.remove(previous, particle);
208 			particle = previous;
209 		}
210 	}
211 }
212