1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or(at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "ags/plugins/ags_waves/ags_waves.h"
24 
25 namespace AGS3 {
26 namespace Plugins {
27 namespace AGSWaves {
28 
FireUpdate(ScriptMethodParams & params)29 void AGSWaves::FireUpdate(ScriptMethodParams &params) {
30 	PARAMS2(int, getDynamicSprite, bool, Fire2Visible);
31 
32 	BITMAP *src = _engine->GetSpriteGraphic(getDynamicSprite);
33 	uint32 **pixel_src = (uint32 **)_engine->GetRawBitmapSurface(src);
34 	int32 src_width = 640;
35 	int32 src_height = 360;
36 	int32 src_depth = 32;
37 	_engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
38 
39 	//OUTLINE
40 	creationdelay += int(2.0);
41 	if (creationdelay > 4 && Fire2Visible) {
42 		int by = 0;
43 		while (by < 6) {
44 			int dnx = 95 + (Random(535 - 95));
45 			int dny = Random(236);
46 
47 			PluginMethod sfGetRegionXY = _engine->GetScriptFunctionAddress("GetRegionAt");
48 			int getID = sfGetRegionXY(dnx, dny);
49 
50 			while (getID != 10) {
51 				dnx = 95 + (Random(535 - 95));
52 				dny = Random(236);
53 				getID = sfGetRegionXY(dnx, dny);
54 			}
55 			CreateDustParticle(dnx, dny);
56 			by++;
57 		}
58 
59 		creationdelay = 0;
60 	}
61 	int h = dsizeDust - 1;
62 	while (h > 0) {
63 		if (dusts[h].life > 0) {
64 			dusts[h].life -= int(2.0);
65 
66 			int setX = dusts[h].x;
67 			int setY = dusts[h].y;
68 
69 			if (setX < 0) setX = 0;
70 			if (setX > src_width) setX = src_width;
71 
72 			if (setY < 0) setY = 0;
73 			if (setY > src_height) setY = src_height;
74 
75 			int Rf = Random(100);
76 			int rv, gv, bv, av;
77 
78 			if (Rf < 50) {
79 				rv = 255; gv = 128; bv = 0;
80 			} else {
81 				rv = 231; gv = 71; bv = 24;
82 			}
83 
84 			av = int((float(255 * (150 - dusts[h].transp))) / 100.0);
85 
86 
87 			pixel_src[setY][setX] = SetColorRGBA(rv, gv, bv, av);
88 
89 			//drawt.DrawImage(dusts[h].x, dusts[h].y, sg, dusts[h].transp);
90 			dusts[h].timlay += int(8.0);
91 			if (dusts[h].timlay > dusts[h].mlay) {
92 				dusts[h].timlay = 0;
93 				dusts[h].x += dusts[h].dx + Random(1);
94 				dusts[h].y += dusts[h].dy - (Random(1));
95 			}
96 			dusts[h].translay += 2;
97 			if (dusts[h].translay >= dusts[h].translayHold) {
98 				if (dusts[h].transp <= 99) dusts[h].transp++;
99 				else dusts[h].life = 0;
100 			}
101 		} else {
102 			dusts[h].active = false;
103 		}
104 		h--;
105 	}
106 
107 	_engine->ReleaseBitmapSurface(src);
108 }
109 
WindUpdate(ScriptMethodParams & params)110 void AGSWaves::WindUpdate(ScriptMethodParams &params) {
111 	PARAMS4(int, ForceX, int, ForceY, int, Transparency, int, sprite);
112 
113 	BITMAP *src = _engine->GetSpriteGraphic(sprite);
114 	int32 src_width = 640;
115 	int32 src_height = 360;
116 	int32 src_depth = 32;
117 	_engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
118 	uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
119 
120 	int by = 0;
121 	while (by < 2) {
122 		int dnx = Random(ww + 250) - 250;
123 		int dny = Random(hh);
124 		CreateParticle(dnx, dny, ForceX, ForceY);
125 		by++;
126 	}
127 
128 	int dnx;
129 	if (ForceX > 0) dnx = (Random(ww + 250) - 250) - (50 + Random(100));
130 	else dnx = Random(ww + 250) - 250;
131 	//
132 	int dny = Random(hh);
133 	CreateParticle2(dnx, dny, ForceX, ForceY);
134 
135 
136 	dnx = -(20 + Random(50));//Random(ww);
137 	if (dnx < -160) dnx = -160;
138 	if (dnx > ww + 160) dnx = ww + 160;
139 
140 	dny = Random(hh);
141 	CreateParticleF(dnx, dny, ForceX, ForceY);
142 
143 	int h = dsize - 1;
144 
145 	if (h < dsizeF - 1) {
146 		h = dsizeF - 1;
147 	}
148 
149 	int setByx = 0;
150 	if (proom == 3 && prevroom == 14) {
151 		setByx = 640;
152 	}
153 	if (proom == 4 && prevroom == 8) {
154 		setByx -= 480;
155 	}
156 	while (h > 0) {
157 		if (particles[h].life > 0) {
158 			particles[h].life -= int(3.0);
159 			particles[h].doingCircleChance -= 2;
160 			int df = 100 - particles[h].transp;
161 			df = 10 - (df / 4);
162 
163 			int pwidth = particles[h].width + df;
164 			int pheight = particles[h].height + df;
165 
166 			int px = particles[h].x - (pwidth / 2);
167 			int py = particles[h].y - (pheight / 2);
168 			int tp = particles[h].transp + Transparency;
169 
170 			if (tp > 100) tp = 100;
171 
172 			int pgraph = 0;
173 			int SplitBetweenTwo = Random(100);
174 			if (SplitBetweenTwo <= 50) pgraph = 813;
175 			else pgraph = 4466;
176 
177 			if (tp != 100) {
178 
179 				BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particles[h].frame);
180 
181 
182 				int32 src2_width = 640;
183 				int32 src2_height = 360;
184 				int32 src2_depth = 32;
185 				_engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
186 				uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
187 				_engine->ReleaseBitmapSurface(src2);
188 
189 				int startx = px + setByx;
190 				int endx = px + setByx + src2_width;
191 				int starty = py;
192 				int endy = py + src2_height;
193 
194 
195 
196 				int x, y;
197 				int ny = 0;
198 				for (y = starty; y < endy; y++) {
199 					int nx = 0;
200 					for (x = startx; x < endx; x++) {
201 						int setX = nx;
202 						int setY = ny;
203 						if (setX < 0)setX = 0;
204 						if (setX > src2_width - 1) setX = src2_width - 1;
205 						if (setY < 0) setY = 0;
206 						if (setY > src2_height - 1) setY = src2_height - 1;
207 
208 						int netX = x;
209 						int netY = y;
210 
211 
212 						if (netX < 0) netX = 0;
213 						if (netX > src_width - 1) netX = src_width - 1;
214 						if (netY < 0) netY = 0;
215 						if (netY > src_height - 1) netY = src_height - 1;
216 
217 						int clr = sprite_pixels2[setY][setX];
218 						int rv = getRcolor(clr);
219 						int gv = getGcolor(clr);
220 						int bv = getBcolor(clr);
221 						int av = getAcolor(clr);
222 
223 						av = int(float((av * (100 - tp))) / 100.0);
224 
225 						sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
226 						nx++;
227 					}
228 					ny++;
229 				}
230 
231 			}
232 			particles[h].timlay += int(6.0);
233 			if (particles[h].timlay > particles[h].mlay) {
234 				particles[h].frame++;
235 				if (particles[h].frame > 6) particles[h].frame = 0;
236 				particles[h].timlay = 0;
237 				particles[h].x += particles[h].dx + particles[h].fx;
238 				particles[h].y += particles[h].dy + particles[h].fy;//Random(1);
239 			}
240 			particles[h].translay += 2;
241 			if (particles[h].translay >= particles[h].translayHold) {
242 				if (particles[h].transp <= 99) particles[h].transp++;
243 				else {
244 					particles[h].life = 0;
245 				}
246 			}
247 			if (particles[h].x >= (ww - 90) + setByx || particles[h].x < 90 + setByx) {
248 				if (particles[h].transp <= 99)particles[h].transp++;
249 				else {
250 					particles[h].life = 0;
251 				}
252 			}
253 
254 			if (!particles[h].doingcircle && particles[h].angle == 0.0
255 				&& particles[h].doingCircleChance <= 0) {
256 				particles[h].doingcircle = true;
257 			}
258 			if (particles[h].doingcircle) {
259 				particles[h].angleLay += float(1 + WForceX[h]) * 1.5;
260 				if (particles[h].angleLay > 12.0) {
261 					particles[h].angleLay = 0.0;
262 					particles[h].angle += particles[h].anglespeed;
263 					int Y = particles[h].y + int((sin(particles[h].angle) * particles[h].radius));
264 					int X = particles[h].x + int((cos(particles[h].angle) * particles[h].radius));
265 					particles[h].x = X;
266 					particles[h].y = Y;
267 				}
268 			}
269 			particles[h].fx = ForceX;
270 			particles[h].fy = ForceY;
271 
272 		} else {
273 			particles[h].active = false;
274 		}
275 
276 
277 
278 
279 
280 
281 		if (h <= 5 && particlesF[h].life > 0) {
282 			int pwidth = particlesF[h].width;
283 			int pheight = particlesF[h].height;
284 			int px = particlesF[h].x - (pwidth / 2);
285 			int py = particlesF[h].y - (pheight / 2);
286 			int pgraph = 0;
287 			int SplitBetweenTwo = Random(100);
288 			if (SplitBetweenTwo <= 50) pgraph = 806;
289 			else pgraph = 4459;
290 
291 			int tp = particlesF[h].transp + Transparency;
292 			if (tp > 100) tp = 100;
293 
294 
295 			if (tp != 100) {
296 
297 				BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particlesF[h].frame);
298 				int32 src2_width = 640;
299 				int32 src2_height = 360;
300 				int32 src2_depth = 32;
301 				_engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
302 				uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
303 				_engine->ReleaseBitmapSurface(src2);
304 
305 				int startx = px + setByx;
306 				int endx = px + setByx + src2_width;
307 				int starty = py;
308 				int endy = py + src2_height;
309 
310 
311 				int x, y;
312 				int ny = 0;
313 				for (y = starty; y < endy; y++) {
314 					int nx = 0;
315 					for (x = startx; x < endx; x++) {
316 						int setX = nx;
317 						int setY = ny;
318 						if (setX < 0)setX = 0;
319 						if (setX > src2_width - 1) setX = src2_width - 1;
320 						if (setY < 0) setY = 0;
321 						if (setY > src2_height - 1) setY = src2_height - 1;
322 
323 						int netX = x;
324 						int netY = y;
325 
326 
327 						if (netX < 0) netX = 0;
328 						if (netX > src_width - 1) netX = src_width - 1;
329 						if (netY < 0) netY = 0;
330 						if (netY > src_height - 1) netY = src_height - 1;
331 
332 						int clr = sprite_pixels2[setY][setX];
333 						int rv = getRcolor(clr);
334 						int gv = getGcolor(clr);
335 						int bv = getBcolor(clr);
336 						int av = getAcolor(clr);
337 
338 						av = int(float((av * (100 - tp))) / 100.0);
339 
340 						sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
341 
342 						nx++;
343 					}
344 					ny++;
345 				}
346 
347 
348 
349 
350 				// drawt.DrawImage(px+setByx, py, , tp, pwidth, pheight);
351 			}
352 			particlesF[h].timlay += int(6.0);
353 			if (particlesF[h].timlay > particlesF[h].mlay) {
354 				particlesF[h].frame++;
355 				if (particlesF[h].frame > 6)  particlesF[h].frame = 0;
356 				particlesF[h].timlay = 0;
357 				particlesF[h].x += particlesF[h].dx + ForceX;
358 				particlesF[h].y += particlesF[h].dy + ForceY;
359 			}
360 
361 
362 			if (particlesF[h].x >= ww - 90 || particlesF[h].x < 90) {
363 				particlesF[h].translay += 2;
364 				if (particlesF[h].translay >= particlesF[h].translayHold) {
365 					if (particlesF[h].transp <= 99) particlesF[h].transp++;
366 					else {
367 						particlesF[h].life = 0;
368 					}
369 				}
370 			}
371 		} else {
372 			if (h <= 9)  particlesF[h].active = false;
373 		}
374 
375 
376 		//SECOND PARTICLES
377 		if (h <= 10) {
378 			if (particles2[h].life > 0) {
379 				particles2[h].life -= int(3.0);
380 				particles2[h].doingCircleChance -= 1;
381 				int df = 100 - particles2[h].transp;//45-0
382 				df = 10 - (df / 4);//10-0
383 
384 				int pwidth = particles2[h].width + df;
385 				int pheight = particles2[h].height + df;
386 
387 				int px = particles2[h].x - (pwidth / 2);
388 				int py = particles2[h].y - (pheight / 2);
389 				int tp = particles2[h].transp + Transparency;
390 
391 				if (tp > 100) tp = 100;
392 
393 				int pgraph = 5224;
394 
395 				if (tp != 100) {
396 
397 					BITMAP *src2 = _engine->GetSpriteGraphic(pgraph + particles2[h].frame);
398 
399 
400 					int32 src2_width = 640;
401 					int32 src2_height = 360;
402 					int32 src2_depth = 32;
403 					_engine->GetBitmapDimensions(src2, &src2_width, &src2_height, &src2_depth);
404 					uint32 **sprite_pixels2 = (uint32 **)_engine->GetRawBitmapSurface(src2);
405 					_engine->ReleaseBitmapSurface(src2);
406 
407 					int startx = px + setByx;
408 					int endx = px + setByx + src2_width;
409 					int starty = py;
410 					int endy = py + src2_height;
411 
412 
413 
414 					int x, y;
415 					int ny = 0;
416 					for (y = starty; y < endy; y++) {
417 						int nx = 0;
418 						for (x = startx; x < endx; x++) {
419 							int setX = nx;
420 							int setY = ny;
421 							if (setX < 0)setX = 0;
422 							if (setX > src2_width - 1) setX = src2_width - 1;
423 							if (setY < 0) setY = 0;
424 							if (setY > src2_height - 1) setY = src2_height - 1;
425 
426 							int netX = x;
427 							int netY = y;
428 
429 
430 							if (netX < 0) netX = 0;
431 							if (netX > src_width - 1) netX = src_width - 1;
432 							if (netY < 0) netY = 0;
433 							if (netY > src_height - 1) netY = src_height - 1;
434 
435 							int clr = sprite_pixels2[setY][setX];
436 							int rv = getRcolor(clr);
437 							int gv = getGcolor(clr);
438 							int bv = getBcolor(clr);
439 							int av = getAcolor(clr);
440 
441 							av = int(float((av * (100 - tp))) / 100.0);
442 
443 							sprite_pixels[netY][netX] = SetColorRGBA(rv, gv, bv, av);
444 							nx++;
445 						}
446 						ny++;
447 					}
448 
449 
450 				}
451 				particles2[h].timlay += int(6.0);
452 				if (particles2[h].timlay > particles2[h].mlay) {
453 					particles2[h].frame++;
454 					if (particles2[h].frame > 7) particles2[h].frame = 0;
455 					particles2[h].timlay = 0;
456 					particles2[h].x += particles2[h].dx + particles2[h].fx;
457 					particles2[h].y += particles2[h].dy + particles2[h].fy;//Random(1);
458 				}
459 				particles2[h].translay += 2;
460 				if (particles2[h].translay >= particles2[h].translayHold) {
461 					if (particles2[h].transp <= 99) particles2[h].transp++;
462 					else {
463 						particles2[h].life = 0;
464 					}
465 				}
466 				if (particles2[h].x >= (ww - 90) + setByx || particles2[h].x < 90 + setByx) {
467 					if (particles2[h].transp <= 99)particles2[h].transp++;
468 					else {
469 						particles2[h].life = 0;
470 					}
471 				}
472 
473 				if (!particles2[h].doingcircle && particles2[h].angle == 0.0
474 					&& particles2[h].doingCircleChance <= 0) {
475 					particles2[h].doingcircle = true;
476 				}
477 				if (particles2[h].doingcircle) {
478 					particles2[h].angleLay += float((1 + WForceX[h + 200]));
479 					if (particles2[h].angleLay > 12.0) {
480 						particles2[h].angleLay = 0.0;
481 						particles2[h].angle += particles2[h].anglespeed;
482 						int Y = particles2[h].y + int((sin(particles2[h].angle) * particles2[h].radius));
483 						int X = particles2[h].x + int((cos(particles2[h].angle) * particles2[h].radius));
484 						particles2[h].x = X;
485 						particles2[h].y = Y;
486 					}
487 				}
488 				particles2[h].fx = int(float(ForceX) * 3.5);
489 				particles2[h].fy = int(float(ForceY) * 3.5);
490 
491 			} else {
492 				particles2[h].active = false;
493 			}
494 		}
495 
496 		// SECOND PARTICLES
497 		h--;
498 	}
499 
500 	_engine->ReleaseBitmapSurface(src);
501 }
502 
SetWindValues(ScriptMethodParams & params)503 void AGSWaves::SetWindValues(ScriptMethodParams &params) {
504 	PARAMS4(int, w, int, h, int, pr, int, prev);
505 
506 	ww = w;
507 	hh = h;
508 	proom = pr;
509 	prevroom = prev;
510 }
511 
RainUpdate(ScriptMethodParams & params)512 void AGSWaves::RainUpdate(ScriptMethodParams &params) {
513 	PARAMS7(int, rdensity, int, FX, int, FY, int, RW, int, RH, int, graphic, float, perc);
514 
515 	bool drawBack = true;
516 	bool drawMid = true;
517 	bool drawFore = true;
518 	int h = 0;
519 
520 	int cdelay = 0;
521 	while (cdelay < rdensity) {
522 		if (drawMid) CreateRainParticleMid(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((400.0 * perc) / 100.0));
523 		if (drawFore) CreateRainParticleFore(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((40.0 * perc) / 100.0));
524 		if (drawBack) {
525 			CreateRainParticleBack(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((800.0 * perc) / 100.0));
526 			CreateRainParticleBack(Random(640 * 4) - 640, -(20 + Random(50)), FX, FY, int((800.0 * perc) / 100.0));
527 		}
528 		cdelay++;
529 	}
530 
531 	BITMAP *src = _engine->GetSpriteGraphic(graphic);
532 	int32 src_width = 640;
533 	int32 src_height = 360;
534 	int32 src_depth = 32;
535 	_engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
536 //	uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
537 
538 	int rotAngle = 6;
539 	int rotTrans = 60 + Random(40 + 60);//Random(103)+122;
540 	int rotX = -50;
541 	int rotY = 120;
542 	int totalTrans = 0;
543 
544 	int maxPart = 800;
545 	if (!drawBack) maxPart = 400;
546 	if (!drawMid) maxPart = 400;
547 
548 	while (h < maxPart) {
549 		if (h < 400 && drawMid)RainParticles[h].x = RainParticles[h].x - RW;
550 		if (h < 400 && drawFore)RainParticlesFore[h].x = RainParticlesFore[h].x - RW;
551 		RainParticlesBack[h].x = RainParticlesBack[h].x - RW;
552 
553 		h++;
554 	}
555 
556 	h = 0;
557 	//BACK
558 	while (h < maxPart) {
559 		//FORE
560 		if (h < 400 && drawFore) {
561 			if (RainParticlesFore[h].life > 0 && RainParticlesFore[h].active) {
562 				RainParticlesFore[h].life -= 4;
563 				RainParticlesFore[h].translay += 2;
564 				if (RainParticlesFore[h].translay > RainParticlesFore[h].transhold) {
565 					RainParticlesFore[h].translay = 0;
566 					RainParticlesFore[h].trans += 2;
567 				}
568 
569 				int setRainTrans = RainParticlesFore[h].trans + 8 + Random(10) + totalTrans;
570 				if (setRainTrans > 100) {
571 					setRainTrans = 100;
572 				}
573 
574 				if (RainParticlesFore[h].y > RH + 30
575 					|| RainParticlesFore[h].trans == 100) {
576 					RainParticlesFore[h].active = false;
577 				} else {
578 					//int thick =3;
579 					//DRAW LINE
580 					int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
581 
582 					int x1 = RainParticlesFore[h].x;
583 					int y1 = RainParticlesFore[h].y;
584 					int x2 = RainParticlesFore[h].x + (RainParticlesFore[h].fx * 2);
585 					int y2 = RainParticlesFore[h].y + (RainParticlesFore[h].fy * 2);
586 
587 					DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 120, 255 - 120, 255 - 120, alpha - 80, 6);
588 					DrawLineCustom(x1 - 1, y1, x2 - 1, y2, graphic, 255 - 120, 255 - 120, 255 - 120, alpha - 80, 6);
589 
590 					DrawLineCustom((x1 - rotX), y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 120, 255 - 120, 255 - 120, (alpha - 80) - rotTrans, 6);
591 					DrawLineCustom((x1 - 1) - rotX, y1 - rotY, ((x2 - 1) - rotX) - rotAngle, y2 - rotY, graphic, 255 - 120, 255 - 120, 255 - 120, (alpha - 80) - rotTrans, 6);
592 
593 					RainParticlesFore[h].x += RainParticlesFore[h].fx;
594 					RainParticlesFore[h].y += RainParticlesFore[h].fy;
595 				}
596 			} else {
597 				RainParticlesFore[h].life = 0;
598 				RainParticlesFore[h].active = false;
599 			}
600 		}
601 		//FORE
602 
603 		//MID
604 		if (!h && drawMid /* h < drawMid */) {
605 			if (RainParticles[h].life > 0 && RainParticles[h].active) {
606 				RainParticles[h].life -= 4;
607 
608 				RainParticles[h].translay += 2;
609 				if (RainParticles[h].translay > RainParticles[h].transhold) {
610 					RainParticles[h].translay = 0;
611 					RainParticles[h].trans += 3;
612 				}
613 
614 
615 				int setRainTrans = RainParticles[h].trans + 4 + Random(5) + totalTrans;
616 				if (setRainTrans > 100) {
617 					setRainTrans = 100;
618 				}
619 
620 				if (RainParticles[h].y > RH + 30
621 					|| RainParticles[h].trans == 100) {
622 					RainParticles[h].active = false;
623 				} else {
624 					//int thick=2;
625 					//DRAW LINE
626 					int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
627 
628 					int x1 = RainParticles[h].x;
629 					int y1 = RainParticles[h].y;
630 					int x2 = RainParticles[h].x + RainParticles[h].fx;
631 					int y2 = RainParticles[h].y + RainParticles[h].fy;
632 
633 					DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 40, 255 - 40, 255 - 40, alpha, 6);
634 					DrawLineCustom(x1 - 1, y1, x2 - 1, y2, graphic, 255 - 40, 255 - 40, 255 - 40, alpha, 6);
635 
636 					DrawLineCustom((x1)-rotX, y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 40, 255 - 40, 255 - 40, alpha - rotTrans, 6);
637 					DrawLineCustom((x1 - 1) - rotX, y1 - rotY, ((x2 - 1) - rotX) - rotAngle, y2 - rotY, graphic, 255 - 40, 255 - 40, 255 - 40, alpha - rotTrans, 6);
638 
639 					RainParticles[h].x += RainParticles[h].fx;
640 					RainParticles[h].y += RainParticles[h].fy;
641 				}
642 
643 			} else {
644 				RainParticles[h].life = 0;
645 				RainParticles[h].active = false;
646 			}
647 		}
648 		//MID
649 		if (h < 800 && drawBack) {
650 			if (RainParticlesBack[h].life > 0 && RainParticlesBack[h].active) {
651 				RainParticlesBack[h].life -= 4;
652 				RainParticlesBack[h].translay += 2;
653 				if (RainParticlesBack[h].translay > RainParticlesBack[h].transhold) {
654 					RainParticlesBack[h].translay = 0;
655 					RainParticlesBack[h].trans++;
656 				}
657 
658 				int setRainTrans = RainParticlesBack[h].trans + totalTrans;//+8+Random(10);
659 				if (setRainTrans > 100) {
660 					setRainTrans = 100;
661 				}
662 
663 				if (RainParticlesBack[h].y > RH + 30
664 					|| RainParticlesBack[h].trans == 100) {
665 					RainParticlesBack[h].active = false;
666 				} else {
667 					//int thick =1;
668 					//DRAW LINE
669 					int x1 = RainParticlesBack[h].x;
670 					int y1 = RainParticlesBack[h].y;
671 					int x2 = RainParticlesBack[h].x + RainParticlesBack[h].fx;
672 					int y2 = RainParticlesBack[h].y + RainParticlesBack[h].fy;
673 
674 					int alpha = int(float((255 * (100 - setRainTrans))) / 100.0);
675 					DrawLineCustom(x1, y1, x2, y2, graphic, 255 - 80, 255 - 80, 255 - 80, alpha, 3);
676 					DrawLineCustom((x1 - rotX), y1 - rotY, (x2 - rotX) - rotAngle, y2 - rotY, graphic, 255 - 80, 255 - 80, 255 - 80, alpha - rotTrans, 3);
677 
678 					RainParticlesBack[h].x += RainParticlesBack[h].fx;
679 					RainParticlesBack[h].y += RainParticlesBack[h].fy;
680 				}
681 			} else {
682 				RainParticlesBack[h].life = 0;
683 				RainParticlesBack[h].active = false;
684 			}
685 		}
686 		h++;
687 	}
688 
689 	// BACK
690 	_engine->ReleaseBitmapSurface(src);
691 }
692 
693 
DrawLineCustom(int x1,int y1,int x2,int y2,int graphic,int setR,int setG,int setB,int setA,int TranDif)694 void AGSWaves::DrawLineCustom(int x1, int y1, int x2, int y2, int graphic, int setR, int setG, int setB, int setA, int TranDif) {
695 	int ALine = 0;
696 	BITMAP *src = _engine->GetSpriteGraphic(graphic);
697 	int32 src_width = 640;
698 	int32 src_height = 360;
699 	int32 src_depth = 32;
700 	_engine->GetBitmapDimensions(src, &src_width, &src_height, &src_depth);
701 	uint32 **sprite_pixels = (uint32 **)_engine->GetRawBitmapSurface(src);
702 
703 	int DiffA = -26;
704 
705 	int x, y;
706 	int xe;
707 	int ye;
708 	int dx = x2 - x1;
709 	int dy = y2 - y1;
710 	int dx1 = abs(dx);
711 	int dy1 = abs(dy);
712 	int px = (2 * dy1) - dx1;
713 	int py = (2 * dx1) - dy1;
714 	if (dy1 <= dx1) {
715 		if (dx >= 0) {
716 			x = x1;
717 			y = y1;
718 			xe = x2;
719 		} else {
720 			x = x2; y = y2; xe = x1;
721 		}
722 
723 		int xx2 = x - 320;
724 		int yy2 = y;
725 
726 		if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
727 		} else {
728 			sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
729 		}
730 
731 		int xx3 = x + 320;
732 		int yy3 = y;
733 
734 		if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
735 		} else {
736 			sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
737 		}
738 
739 		int xx = x;
740 		int yy = y;
741 
742 		if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
743 		} else {
744 			sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
745 			ALine++;
746 		}
747 
748 		int i = 0;
749 		while (x < xe) {
750 			x = x + 1;
751 			if (px < 0) {
752 				px = px + 2 * dy1;
753 			} else {
754 				if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
755 					y = y + 1;
756 				} else {
757 					y = y - 1;
758 				}
759 				px = px + 2 * (dy1 - dx1);
760 			}
761 
762 			xx2 = x - 320;
763 			yy2 = y;
764 			if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
765 			} else {
766 				sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
767 			}
768 			xx3 = x + 320;
769 			yy3 = y;
770 			if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
771 			} else {
772 				sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
773 			}
774 
775 			xx = x;
776 			yy = y;
777 			if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
778 			} else {
779 				sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
780 				ALine++;
781 			}
782 
783 			i++;
784 		}
785 	} else {
786 		if (dy >= 0) {
787 			x = x1;
788 			y = y1;
789 			ye = y2 - 1;
790 		} else {
791 			// Line is drawn top to bottom
792 			x = x2;
793 			y = y2;
794 			ye = y1 - 1;
795 		}
796 
797 		int xx2 = x - 320;
798 		int yy2 = y;
799 
800 		if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
801 		} else {
802 			sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
803 		}
804 
805 		int xx3 = x + 320;
806 		int yy3 = y;
807 
808 		if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
809 		} else {
810 			sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
811 		}
812 		int xx = x;
813 		int yy = y;
814 
815 		if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
816 		} else {
817 			sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
818 			ALine++;
819 		}
820 
821 		int i = 0;
822 		while (y < ye) {
823 			y = y + 1;
824 			if (py <= 0) {
825 				py = py + (2 * dx1);
826 			} else {
827 				if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) {
828 					x = x + 1;
829 				} else {
830 					x = x - 1;
831 				}
832 				py = py + 2 * (dx1 - dy1);
833 			}
834 			xx2 = x - 320;
835 			yy2 = y;
836 			if (xx2 < 0 || xx2 > src_width - 1 || yy2 > src_height - 1 || yy2 < 0) {
837 			} else {
838 				sprite_pixels[yy2][xx2] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
839 			}
840 			xx3 = x + 320;
841 			yy3 = y;
842 			if (xx3 < 0 || xx3 > src_width - 1 || yy3 > src_height - 1 || yy3 < 0) {
843 			} else {
844 				sprite_pixels[yy3][xx3] = SetColorRGBA(setR, setG, setB, setA + DiffA + (ALine * TranDif));
845 			}
846 			xx = x;
847 			yy = y;
848 			if (xx < 0 || xx > src_width - 1 || yy > src_height - 1 || yy < 0) {
849 			} else {
850 				sprite_pixels[yy][xx] = SetColorRGBA(setR, setG, setB, setA + (ALine * TranDif));
851 				ALine++;
852 			}
853 			i++;
854 		}
855 	}
856 
857 	_engine->ReleaseBitmapSurface(src);
858 }
859 
CreateParticle(int xx,int yy,int ForceX,int ForceY)860 void AGSWaves::CreateParticle(int xx, int yy, int ForceX, int ForceY) {
861 	int h = 0;
862 	bool foundparticle = false;
863 	int fid = -1;
864 	while (h <= dsize && !foundparticle) {
865 		if (particles[h].active == false) {
866 			foundparticle = true;
867 			fid = h;
868 		}
869 		h++;
870 	}
871 
872 	if (foundparticle) {
873 		int d = fid;
874 		particles[d].x = xx;
875 		particles[d].y = yy;
876 		particles[d].dx = 0;
877 		particles[d].dy = 0;
878 		particles[d].life = 20000;
879 		particles[d].transp = 55 + Random(10);
880 		particles[d].active = true;
881 		particles[d].mlay = 4 + Random(2);
882 		particles[d].timlay = 0;
883 		particles[d].translay = 0;
884 		particles[d].translayHold = 19 + Random(15);
885 		particles[d].width = 2 + Random(2);
886 		particles[d].height = particles[d].width;
887 		particles[d].fx = 0;
888 		particles[d].fy = 0;
889 		particles[d].doingcircle = false;
890 		particles[d].angle = 0.0;
891 		particles[d].radius = 4.0 + float(Random(6));
892 		particles[d].doingCircleChance = Random(200);
893 		particles[d].angleLay = 0.0;
894 		particles[d].frame = 0;
895 		particles[d].anglespeed = float(Random(20)) / 100.0;
896 		WForceX[d] = ForceX;
897 		WForceY[d] = ForceY;
898 		if (dsize < (raysize - 1)) dsize++;
899 	}
900 }
901 
CreateParticle2(int xx,int yy,int ForceX,int ForceY)902 void AGSWaves::CreateParticle2(int xx, int yy, int ForceX, int ForceY) {
903 	int h = 0;
904 	bool foundparticle = false;
905 	int fid = -1;
906 	while (h <= dsize2 && !foundparticle) {
907 		if (particles2[h].active == false) {
908 			foundparticle = true;
909 			fid = h;
910 		}
911 		h++;
912 	}
913 
914 	if (foundparticle) {
915 		int d = fid;
916 		particles2[d].x = xx;
917 		particles2[d].y = yy;
918 		particles2[d].dx = 0;
919 		particles2[d].dy = 0;
920 		particles2[d].life = 20000;
921 		particles2[d].transp = 65 + Random(15);
922 		particles2[d].active = true;
923 		particles2[d].mlay = 4 + Random(2);
924 		particles2[d].timlay = 0;
925 		particles2[d].translay = 0;
926 		particles2[d].translayHold = 19 + Random(15);
927 		particles2[d].width = 16;
928 		particles2[d].height = particles[d].width;
929 		particles2[d].fx = 0;
930 		particles2[d].fy = 0;
931 		particles2[d].doingcircle = false;
932 		particles2[d].angle = 0.0;
933 		particles2[d].radius = 4.0 + float(Random(6));
934 		particles2[d].doingCircleChance = Random(200);
935 		particles2[d].angleLay = 0.0;
936 		particles2[d].frame = 0;
937 		particles2[d].anglespeed = float(Random(20)) / 100.0;
938 		WForceX[d + 200] = ForceX;
939 		WForceY[d + 200] = ForceY;
940 		if (dsize2 < (raysize2 - 1)) dsize2++;
941 	}
942 }
943 
CreateParticleF(int xx,int yy,int ForceX,int ForceY)944 void AGSWaves::CreateParticleF(int xx, int yy, int ForceX, int ForceY) {
945 	int h = 0;
946 	bool foundparticle = false;
947 	int fid = -1;
948 	while (h <= dsizeF && !foundparticle) {
949 		if (particlesF[h].active == false) {
950 			foundparticle = true;
951 			fid = h;
952 		}
953 		h++;
954 	}
955 
956 	if (foundparticle) {
957 		int d = fid;
958 		particlesF[d].x = xx;
959 		particlesF[d].y = yy;
960 		particlesF[d].dx = (-1) + Random(1);
961 		particlesF[d].dy = (-1) + Random(1);
962 		particlesF[d].life = 20000;
963 		particlesF[d].transp = 45 + Random(10);
964 		particlesF[d].active = true;
965 		particlesF[d].mlay = 4 + Random(2);
966 		particlesF[d].timlay = 0;
967 		particlesF[d].translay = 0;
968 		particlesF[d].translayHold = 19 + Random(15);
969 		particlesF[d].width = 8 + Random(2);
970 		particlesF[d].height = particlesF[d].width;
971 		particlesF[d].fx = 0;
972 		particlesF[d].fy = 0;
973 		particlesF[d].doingcircle = false;
974 		particlesF[d].angle = 0.0;
975 		particlesF[d].radius = 4.0 + float(Random(6));
976 		particlesF[d].doingCircleChance = Random(200);
977 		particlesF[d].angleLay = 0.0;
978 		WForceX[d + 100] = ForceX;
979 		WForceY[d + 100] = ForceY;
980 		particlesF[d].frame = 0;
981 		if (dsizeF < (raysizeF - 1)) dsizeF++;
982 
983 	}
984 }
985 
CreateDustParticle(int xx,int yy)986 void AGSWaves::CreateDustParticle(int xx, int yy) {
987 	int h = 0;
988 	bool founddust = false;
989 	int fid = -1;
990 	while (h <= dsizeDust && !founddust) {
991 		if (dusts[h].active == false) {
992 			founddust = true;
993 			fid = h;
994 		}
995 		h++;
996 	}
997 
998 	if (founddust) {
999 		int d = fid;
1000 		dusts[d].x = xx;
1001 		dusts[d].y = yy;
1002 		dusts[d].dx = (-1) + Random(1);
1003 		dusts[d].dy = (-1) + Random(1);
1004 		dusts[d].life = 20000;
1005 		dusts[d].transp = 55 + Random(10);
1006 		dusts[d].active = true;
1007 		dusts[d].mlay = 4 + Random(2);
1008 		dusts[d].timlay = 0;
1009 		dusts[d].translay = 0;
1010 		dusts[d].translayHold = 19 + Random(15);
1011 		if (dsizeDust < (raysizeDust - 1)) dsizeDust++;
1012 	}
1013 }
1014 
CreateRainParticleMid(int x,int y,int fx,int fy,int maxpart)1015 void AGSWaves::CreateRainParticleMid(int x, int y, int fx, int fy, int maxpart) {
1016 	int s = 0;
1017 
1018 	while (s < maxpart) {
1019 		if (!RainParticles[s].active) {
1020 			RainParticles[s].active = true;
1021 			RainParticles[s].x = x;
1022 			RainParticles[s].y = y;
1023 			RainParticles[s].fx = fx;
1024 			RainParticles[s].fy = fy;
1025 			RainParticles[s].life = 2000;
1026 			RainParticles[s].trans = 70 + Random(25);
1027 			RainParticles[s].transhold = Random(3);
1028 			RainParticles[s].translay = 0;
1029 			return;
1030 		}
1031 		s++;
1032 	}
1033 }
1034 
CreateRainParticleFore(int x,int y,int fx,int fy,int maxpart)1035 void AGSWaves::CreateRainParticleFore(int x, int y, int fx, int fy, int maxpart) {
1036 	int s = 0;
1037 
1038 	while (s < maxpart) {
1039 		if (!RainParticlesFore[s].active) {
1040 			RainParticlesFore[s].active = true;
1041 			RainParticlesFore[s].x = x;
1042 			RainParticlesFore[s].y = y;
1043 			RainParticlesFore[s].fx = fx;//int(1.5*float(fx));
1044 			RainParticlesFore[s].fy = fy;//int(1.5*float(fy));
1045 			RainParticlesFore[s].life = 2000;
1046 			RainParticlesFore[s].trans = 75 + Random(15);
1047 			RainParticlesFore[s].transhold = Random(3);
1048 			RainParticlesFore[s].translay = 0;
1049 			return;
1050 		}
1051 		s++;
1052 	}
1053 }
1054 
CreateRainParticleBack(int x,int y,int fx,int fy,int maxpart)1055 void AGSWaves::CreateRainParticleBack(int x, int y, int fx, int fy, int maxpart) {
1056 	int s = 0;
1057 
1058 	while (s < maxpart) {
1059 		if (!RainParticlesBack[s].active) {
1060 			RainParticlesBack[s].active = true;
1061 			RainParticlesBack[s].x = x;
1062 			RainParticlesBack[s].y = y;
1063 			if (fx == 0) fx = 1;
1064 			if (fy == 0) fy = 1;
1065 			RainParticlesBack[s].fx = fx / 2;
1066 			RainParticlesBack[s].fy = fy / 2;
1067 			RainParticlesBack[s].life = 2000;
1068 			RainParticlesBack[s].trans = 70 + Random(15);
1069 			RainParticlesBack[s].transhold = 2 + Random(3);
1070 			RainParticlesBack[s].translay = 0;
1071 			return;
1072 		}
1073 		s++;
1074 	}
1075 }
1076 
1077 } // namespace AGSWaves
1078 } // namespace Plugins
1079 } // namespace AGS3
1080