1 /**
2 Particles.c
3 This file contains some default particle behavior definitions as well as helper functions.
4
5 @author Zapper
6 */
7
8
9 /*-- Helper/Effect Functions --*/
10
CreateMuzzleFlash(int x,int y,int angle,int size)11 global func CreateMuzzleFlash(int x, int y, int angle, int size)
12 {
13 // main muzzle flash
14 CreateParticle("MuzzleFlash", x, y, 0, 0, 10, {Prototype = Particles_MuzzleFlash(), Size = size, Rotation = angle});
15 // and some additional little sparks
16 var xdir = Sin(angle, size * 2);
17 var ydir = -Cos(angle, size * 2);
18 CreateParticle("StarFlash", x, y, PV_Random(xdir - size, xdir + size), PV_Random(ydir - size, ydir + size), PV_Random(20, 60), Particles_Glimmer(), size);
19 }
20
21 // documented in /docs/sdk/script/fn
Smoke(int x,int y,int level,int color,bool heavy)22 global func Smoke(int x, int y, int level, int color, bool heavy)
23 {
24 level = level ?? 10;
25 var particles = Particles_Smoke(heavy);
26 if (color)
27 {
28 particles.Alpha = PV_Linear((color >> 24) & 0xff, 0);
29 particles.R = (color >> 16) & 0xff;
30 particles.G = (color >> 8) & 0xff;
31 particles.B = (color >> 0) & 0xff;
32 }
33 particles.Size = PV_Linear(PV_Random(level/2, level), PV_Random(2 * level, 3 * level));
34 CreateParticle("Smoke", x, y, PV_Random(-level/3, level/3), PV_Random(-level/2, -level/3), PV_Random(level * 2, level * 10), particles, BoundBy(level/5, 3, 20));
35 }
36
37
38 /*-- Particle Definitions --*/
39
Particles_Dust()40 global func Particles_Dust()
41 {
42 return
43 {
44 CollisionVertex = 500,
45 OnCollision = PC_Stop(),
46 ForceX = PV_Wind(20),
47 ForceY = PV_Gravity(25),
48 Alpha = PV_KeyFrames(0, 0, 0, 250, 60, 1000, 0),
49 Rotation = PV_Random(0, 360),
50 Size = PV_KeyFrames(0, 0, 5, 100, 12, 1000, 7)
51 };
52 }
53
Particles_Cloud()54 global func Particles_Cloud()
55 {
56 return
57 {
58 Size = 200,
59 Attach = ATTACH_MoveRelative,
60 Phase = PV_Random(0, 15)
61 };
62 }
63
Particles_Smoke(bool heavy)64 global func Particles_Smoke(bool heavy)
65 {
66 return
67 {
68 CollisionVertex = 500,
69 OnCollision = PC_Stop(),
70 ForceY = PV_Gravity(-100 + heavy*90),
71 ForceX = PV_Wind(200 - heavy*180),
72 DampingX = 900, DampingY = 900,
73 Alpha = PV_Linear(255, 0),
74 R = 100, G = 100, B = 100,
75 Size = PV_Linear(PV_Random(4, 10), PV_Random(20, 30)),
76 Phase = PV_Random(0, 15)
77 };
78 }
79
Particles_Fire()80 global func Particles_Fire()
81 {
82 return
83 {
84 CollisionVertex = 0,
85 OnCollision = PC_Die(),
86 Phase = PV_Random(0, 3, 10),
87 ForceY = PV_Gravity(-100),
88 DampingY = 950,
89 Alpha = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0),
90 BlitMode = GFX_BLIT_Additive,
91 Size = PV_KeyFrames(0, 0, PV_Random(5, 10), 500, 5, 1000, 0),
92 Attach = ATTACH_Front,
93 Rotation = PV_Direction()
94 };
95 }
96
Particles_FireTrail()97 global func Particles_FireTrail()
98 {
99 return
100 {
101 Prototype = Particles_Fire(),
102 ForceY = 0,
103 Attach = nil,
104 };
105 }
106
Particles_Flash(int size)107 global func Particles_Flash(int size)
108 {
109 return
110 {
111 BlitMode = GFX_BLIT_Additive,
112 Alpha = PV_KeyFrames(0, 0, 128, 250, 64, 1000, 0),
113 Size = PV_KeyFrames(0, 0, 0, 100, size ?? 160, 1000, 0),
114 R = 255, G = 255, B = 64
115 };
116 }
117
Particles_Magic()118 global func Particles_Magic()
119 {
120 return
121 {
122 BlitMode = GFX_BLIT_Additive,
123 Alpha = PV_Linear(128, 0),
124 Size = PV_Linear(0, PV_Random(5, 15)),
125 CollisionVertex = 500,
126 OnCollision = PC_Die(),
127 Rotation = PV_Random(0, 360)
128 };
129 }
130
Particles_MagicRing()131 global func Particles_MagicRing()
132 {
133 return
134 {
135 BlitMode = GFX_BLIT_Additive,
136 Alpha = PV_Linear(100, 0),
137 Size = PV_KeyFrames(1, 0, 0, 500, 20, 1000, 0),
138 Attach = ATTACH_Front | ATTACH_MoveRelative
139 };
140 }
141
Particles_Spark()142 global func Particles_Spark()
143 {
144 return
145 {
146 BlitMode = GFX_BLIT_Additive,
147 Size = PV_Linear(PV_Random(5, 15), 0),
148 CollisionVertex = 500,
149 OnCollision = PC_Bounce(500),
150 Rotation = PV_Direction(),
151 ForceY = PV_Gravity(20)
152 };
153 }
154
155 // documented in /docs/sdk/script/fn
Particles_Colored(prototype,color,color2)156 global func Particles_Colored(prototype, color, color2)
157 {
158 // Colors the given particle. If color2 is given, colors in a random fade between color and color2
159 if (GetType(color2))
160 {
161 return {
162 Prototype = prototype,
163 R = PV_Random((color >> 16) & 0xff, (color2 >> 16) & 0xff),
164 G = PV_Random((color >> 8) & 0xff, (color2 >> 8) & 0xff),
165 B = PV_Random((color >> 0) & 0xff, (color2 >> 0) & 0xff),
166 };
167 }
168 else
169 return {
170 Prototype = prototype,
171 R = (color >> 16) & 0xff,
172 G = (color >> 8) & 0xff,
173 B = (color >> 0) & 0xff
174 };
175 }
176
Particles_SparkFire()177 global func Particles_SparkFire()
178 {
179 return
180 {
181 Prototype = Particles_Spark(),
182 R = 255, G = 200, B = 10
183 };
184 }
185
Particles_SmokeTrail()186 global func Particles_SmokeTrail()
187 {
188 return
189 {
190 Prototype = Particles_Smoke(),
191 ForceY = PV_Gravity(-10),
192 ForceX = PV_Wind(20),
193 DampingX = 950, DampingY = 950,
194 Alpha = PV_Linear(128, 0),
195 Size = PV_KeyFrames(0, 0, 0, 200, PV_Random(3, 10), 1000, PV_Random(8, 11))
196 };
197 }
198
Particles_Material(int color)199 global func Particles_Material(int color)
200 {
201 return
202 {
203 Stretch = PV_Speed(2000),
204 CollisionVertex = 1000,
205 OnCollision = PC_Die(),
206 Size = 1,
207 Rotation = PV_Direction(),
208 ForceY = PV_Gravity(100),
209 R = (color >> 16) & 0xff,
210 G = (color >> 8) & 0xff,
211 B = (color >> 0) & 0xff
212 };
213 }
214
Particles_Trajectory()215 global func Particles_Trajectory()
216 {
217 return
218 {
219 BlitMode = GFX_BLIT_Additive,
220 Attach = ATTACH_Front | ATTACH_MoveRelative
221 };
222 }
223
Particles_WoodChip()224 global func Particles_WoodChip()
225 {
226 return
227 {
228 Size = PV_Random(1, 3),
229 Phase = PV_Linear(0, 3),
230 Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0),
231 CollisionVertex = 500,
232 OnCollision = PC_Stop(),
233 ForceX = PV_Wind(50),
234 ForceY = PV_Gravity(100),
235 DampingX = 975, DampingY = 975,
236 Rotation = PV_Direction(PV_Random(750, 1250)),
237 Attach = ATTACH_Front
238 };
239 }
240
Particles_Straw()241 global func Particles_Straw()
242 {
243 return
244 {
245 Prototype = Particles_WoodChip(),
246 Phase = PV_Random(0, 3),
247 Size = PV_Random(3, 5),
248 Attach = nil
249 };
250 }
251
Particles_Leaf(int color)252 global func Particles_Leaf(int color)
253 {
254 return
255 {
256 Size = PV_Random(4, 6),
257 Phase = PV_Random(0, 2),
258 Rotation = PV_Random(0, 360),
259 R = (color >> 16) & 0xff,
260 G = (color >> 8) & 0xff,
261 B = (color >> 0) & 0xff,
262 Alpha = PV_KeyFrames(0, 0, 255, 900, 255, 1000, 0),
263 CollisionVertex = 800,
264 OnCollision = PC_Die(),
265 ForceX = PV_Wind(50),
266 ForceY = PV_Gravity(100),
267 DampingX = 975, DampingY = 975,
268 Rotation = PV_Direction(PV_Random(750, 1250)),
269 Attach = ATTACH_Front
270 };
271 }
272
Particles_CottonBalloon()273 global func Particles_CottonBalloon()
274 {
275 return
276 {
277 Prototype = Particles_WoodChip(),
278 Phase = PV_Random(0, 3),
279 Size = PV_Random(2, 4),
280 ForceY = PV_Gravity(10),
281 DampingX = 900, DampingY = 900,
282 Attach = nil
283 };
284 }
285
Particles_Air()286 global func Particles_Air()
287 {
288 return
289 {
290 Stretch = PV_Speed(500, 1000),
291 Alpha = PV_Linear(255, 0),
292 Phase = PV_Random(0, 3),
293 DampingX = 990, DampingY = 990,
294 ForceX = PV_Random(-5, 5, 30),
295 ForceY = PV_Gravity(10, PV_Random(-5, 5)),
296 Size = PV_KeyFrames(0, 0, 0, 100, PV_Random(20, 30), 1000, 0),
297 Rotation = PV_Direction(),
298 CollisionVertex = 1000,
299 OnCollision = PC_Bounce(500)
300 };
301 }
302
Particles_Thrust(int size)303 global func Particles_Thrust(int size)
304 {
305 size = size ?? 10;
306 return
307 {
308 Size = PV_KeyFrames(0, 0, 0, 50, size, 1000, size * 2),
309 Alpha = PV_Linear(255, 0),
310 R = PV_KeyFrames(0, 0, 255, 500, 100, 1000, 50),
311 G = PV_KeyFrames(0, 0, 255, 500, 100, 1000, 50),
312 B = PV_KeyFrames(0, 0, 255, 500, 100, 1000, 50),
313 Phase = PV_Random(0, 3, 10),
314 Rotation = PV_Random(0, 360),
315 DampingX = 950, DampingY = 950,
316 ForceY = PV_KeyFrames(0, 0, 0, 500, 0, 1000, PV_Gravity(20)),
317 ForceX = PV_KeyFrames(0, 0, 0, 500, 0, 1000, PV_Wind(50)),
318 CollisionVertex = 750
319 };
320 }
321
Particles_MuzzleFlash()322 global func Particles_MuzzleFlash()
323 {
324 return
325 {
326 Attach = ATTACH_Front | ATTACH_MoveRelative,
327 Size = 20,
328 Phase = PV_Linear(0, 5),
329 BlitMode = GFX_BLIT_Additive
330 };
331 }
332
Particles_Glimmer()333 global func Particles_Glimmer()
334 {
335 return
336 {
337 Size = PV_Linear(2, 0),
338 ForceY = GetGravity(),
339 DampingY = PV_Linear(1000,700),
340 DampingX = PV_Linear(1000,700),
341 Stretch = PV_Speed(1000, 500),
342 Rotation = PV_Direction(),
343 OnCollision = PC_Die(),
344 CollisionVertex = 500,
345 R = 255,
346 G = PV_Linear(128,32),
347 B = PV_Random(0, 128, 2),
348 Alpha = PV_Random(255,0,3),
349 BlitMode = GFX_BLIT_Additive,
350 };
351 }
352
Particles_ElectroSpark1()353 global func Particles_ElectroSpark1()
354 {
355 return
356 {
357 Size = PV_Random(5, 9),
358 Phase = PV_Linear(0, 5),
359 BlitMode = GFX_BLIT_Additive,
360 CollisionVertex = 750,
361 OnCollision = PC_Die(),
362 Rotation = PV_Direction()
363 };
364 }
365
Particles_ElectroSpark2()366 global func Particles_ElectroSpark2()
367 {
368 return
369 {
370 Prototype = Particles_ElectroSpark1(),
371 Phase = PV_Linear(6, 11),
372 };
373 }
374
375
376 /*-- Weather Particles --*/
377
Particles_Rain(int color)378 global func Particles_Rain(int color)
379 {
380 return
381 {
382 CollisionVertex = 0,
383 OnCollision = PC_Die(),
384 ForceY = PV_Gravity(1000),
385 Size = PV_Random(10, 30),
386 R = GetRGBaValue(color, 1),
387 G = GetRGBaValue(color, 2),
388 B = GetRGBaValue(color, 3),
389 Rotation = PV_Direction(),
390 CollisionDensity = 25,
391 Stretch = 3000,
392 };
393 }
394
Particles_Snow(int color)395 global func Particles_Snow(int color)
396 {
397 return
398 {
399 Phase = PV_Random(0, 16),
400 CollisionVertex = 0,
401 OnCollision = PC_Die(),
402 DampingY = 1000,//PV_Cos(PV_Linear(0,1800),5,990),
403 ForceY = 0,//GetGravity()/100,//PV_Gravity(100),
404 // TODO: PV_Random() here?
405 ForceX = PV_Sin(PV_Step(PV_Random(5, 10), PV_Random(0, 180)), PV_Random(5, 8), 0),
406 Size = PV_Random(0, 3),
407 R = GetRGBaValue(color, 1),
408 G = GetRGBaValue(color, 2),
409 B = GetRGBaValue(color, 3),
410 Rotation = PV_Random(360),
411 CollisionDensity = 25,
412 Stretch = 1000,
413 };
414 }
415
Particles_RainSmall(int color)416 global func Particles_RainSmall(int color)
417 {
418 return
419 {
420 CollisionVertex = 0,
421 OnCollision = PC_Die(),
422 ForceY = PV_Gravity(1000),
423 Size = 1,
424 R = GetRGBaValue(color, 1),
425 G = GetRGBaValue(color, 2),
426 B = GetRGBaValue(color, 3),
427 Alpha = 200,
428 Rotation = PV_Direction(),
429 CollisionDensity = 25,
430 Stretch = PV_Speed(4000),
431 };
432 }
433
Particles_Splash(int color)434 global func Particles_Splash(int color)
435 {
436 return
437 {
438 Phase = PV_Linear(0, 4),
439 Alpha = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0),
440 Size = PV_Random(5, 10),
441 R = GetRGBaValue(color, 1),
442 G = GetRGBaValue(color, 2),
443 B = GetRGBaValue(color, 3),
444 Rotation = PV_Random(-5,5),
445 Stretch = PV_Random(500, 1000),
446 };
447 }
448
Particles_SplashWater(int color)449 global func Particles_SplashWater(int color)
450 {
451 return
452 {
453 Phase = PV_Linear(0, 13),
454 Alpha = PV_KeyFrames(0, 0, 255, 500, 255, 1000, 0),
455 Size = PV_Random(2, 5),
456 R = GetRGBaValue(color, 1),
457 G = GetRGBaValue(color, 2),
458 B = GetRGBaValue(color, 3),
459 Rotation = PV_Random(-5,5),
460 Stretch = 3000,
461 Attach = ATTACH_Back,
462 };
463 }
464
Particles_Hail(int color)465 global func Particles_Hail(int color)
466 {
467 return
468 {
469 CollisionVertex = 0,
470 ForceY = PV_Gravity(1000),
471 OnCollision = PC_Stop(),
472 Size = 2,
473 Alpha = PV_KeyFrames(255, 0, 255, 500, 255, 1000, 0),
474 R = GetRGBaValue(color, 1),
475 G = GetRGBaValue(color, 2),
476 B = GetRGBaValue(color, 3),
477 Rotation = PV_Random(360),
478 };
479 }
480