Pixel-Composer/scripts/__VFX/__VFX.gml

298 lines
6.3 KiB
Plaintext
Raw Normal View History

2022-12-13 09:20:36 +01:00
enum ANIM_END_ACTION {
loop,
pingpong,
destroy,
}
enum PARTICLE_BLEND_MODE {
normal,
2023-02-28 09:43:01 +01:00
alpha,
2022-12-13 09:20:36 +01:00
additive
}
2022-12-16 09:18:09 +01:00
function __part(_node) constructor {
2023-09-26 14:35:25 +02:00
seed = irandom(99999);
node = _node;
active = false;
surf = noone;
prevx = 0;
prevy = 0;
x = 0;
y = 0;
2023-03-28 06:58:28 +02:00
speedx = 0;
speedy = 0;
turning = 0;
2023-09-26 14:35:25 +02:00
turnSpd = 0;
2023-03-28 06:58:28 +02:00
drawx = 0;
drawy = 0;
drawrot = 0;
drawsx = 0;
drawsy = 0;
2023-10-01 08:37:54 +02:00
accel = 0;
spVec = [ 0, 0 ];
2023-08-16 20:16:31 +02:00
grav = 0;
gravDir = -90;
gravX = 0;
gravY = 0;
2022-12-13 09:20:36 +01:00
scx = 1;
scy = 1;
2023-10-09 07:36:20 +02:00
sc_sx = 1;
sc_sy = 1;
2023-01-17 08:11:55 +01:00
sct = CURVE_DEF_11;
2022-12-13 09:20:36 +01:00
rot = 0;
follow = false;
rot_s = 0;
col = -1;
2023-01-17 08:11:55 +01:00
blend = c_white;
2022-12-13 09:20:36 +01:00
alp = 1;
alp_draw = alp;
alp_fade = 0;
life = 0;
life_total = 0;
2022-12-16 09:18:09 +01:00
step_int = 0;
2022-12-13 09:20:36 +01:00
anim_speed = 1;
anim_end = ANIM_END_ACTION.loop;
2023-07-25 20:12:40 +02:00
ground = false;
ground_y = 0;
ground_bounce = 0;
ground_friction = 1;
2023-07-25 20:12:40 +02:00
2023-10-06 11:51:11 +02:00
static reset = function() { #region
gml_pragma("forceinline");
surf = noone;
prevx = undefined;
prevy = undefined;
} #endregion
static create = function(_surf, _x, _y, _life) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-13 09:20:36 +01:00
active = true;
surf = _surf;
2023-03-28 06:58:28 +02:00
x = _x;
y = _y;
2022-12-13 09:20:36 +01:00
life = _life;
life_total = life;
2022-12-16 09:18:09 +01:00
node.onPartCreate(self);
} #endregion
2022-12-13 09:20:36 +01:00
static setPhysic = function(_sx, _sy, _ac, _g, _gDir, _turn, _turnSpd) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2023-08-16 20:16:31 +02:00
speedx = _sx;
speedy = _sy;
accel = _ac;
grav = _g;
gravDir = _gDir;
gravX = lengthdir_x(grav, gravDir);
gravY = lengthdir_y(grav, gravDir);
2023-03-28 06:58:28 +02:00
turning = _turn;
turnSpd = _turnSpd;
2023-07-25 20:12:40 +02:00
spVec[0] = point_distance(0, 0, speedx, speedy);
spVec[1] = point_direction(0, 0, speedx, speedy);
} #endregion
static setWiggle = function(wiggle_maps) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
wig_psx = wiggle_maps.wig_psx;
wig_psy = wiggle_maps.wig_psy;
wig_rot = wiggle_maps.wig_rot;
wig_scx = wiggle_maps.wig_scx;
wig_scy = wiggle_maps.wig_scy;
wig_dir = wiggle_maps.wig_dir;
} #endregion
2023-07-25 20:12:40 +02:00
static setGround = function(_ground, _ground_offset, _ground_bounce, _ground_frict) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2023-07-25 20:12:40 +02:00
ground = _ground;
ground_y = y + _ground_offset;
ground_bounce = _ground_bounce;
ground_friction = clamp(1 - _ground_frict, 0, 1);
} #endregion
2023-02-23 07:02:19 +01:00
static setTransform = function(_scx, _scy, _sct, _rot, _rots, _follow) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2023-01-17 08:11:55 +01:00
sc_sx = _scx;
sc_sy = _scy;
sct = _sct;
2022-12-13 09:20:36 +01:00
rot = _rot;
rot_s = _rots;
follow = _follow;
} #endregion
2023-02-23 07:02:19 +01:00
static setDraw = function(_col, _blend, _alp, _fade) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-13 09:20:36 +01:00
col = _col;
2023-01-17 08:11:55 +01:00
blend = _blend;
2022-12-13 09:20:36 +01:00
alp = _alp;
alp_draw = _alp;
alp_fade = _fade;
} #endregion
2022-12-13 09:20:36 +01:00
static kill = function() { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-16 09:18:09 +01:00
active = false;
2023-09-26 14:35:25 +02:00
2022-12-16 09:18:09 +01:00
node.onPartDestroy(self);
} #endregion
2022-12-13 09:20:36 +01:00
static step = function() { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-13 09:20:36 +01:00
if(!active) return;
2023-03-28 06:58:28 +02:00
x += speedx;
2023-07-25 20:12:40 +02:00
2023-09-11 16:08:58 +02:00
random_set_seed(seed + life);
2023-07-25 20:12:40 +02:00
if(ground && y + speedy > ground_y) {
y = ground_y;
speedy = -speedy * ground_bounce;
if(abs(speedy) < 0.1)
speedx *= ground_friction;
2023-07-25 20:12:40 +02:00
} else
y += speedy;
2023-03-28 06:58:28 +02:00
var dirr = point_direction(0, 0, speedx, speedy);
var diss = point_distance(0, 0, speedx, speedy);
2023-08-16 20:16:31 +02:00
diss = max(0, diss + accel);
2023-03-28 06:58:28 +02:00
if(speedx != 0 || speedy != 0) {
dirr += wig_dir.get(seed + life);
2023-03-28 06:58:28 +02:00
if(turning != 0) {
var trn = turnSpd? turning * diss : turning;
dirr += trn
}
2022-12-13 09:20:36 +01:00
}
2023-08-16 20:16:31 +02:00
speedx = lengthdir_x(diss, dirr) + gravX;
speedy = lengthdir_y(diss, dirr) + gravY;
2023-03-28 06:58:28 +02:00
if(follow) rot = spVec[1];
else rot += rot_s;
2022-12-13 09:20:36 +01:00
2022-12-16 09:18:09 +01:00
if(step_int > 0 && safe_mod(life, step_int) == 0)
node.onPartStep(self);
2022-12-13 09:20:36 +01:00
if(life-- < 0) kill();
2023-03-28 06:58:28 +02:00
2023-07-25 20:12:40 +02:00
if(prevx != undefined) {
spVec[0] = point_distance(prevx, prevy, x, y);
spVec[1] = point_direction(prevx, prevy, x, y);
}
2023-03-28 06:58:28 +02:00
prevx = x;
prevy = y;
drawx = x;
drawy = y;
drawrot = rot;
drawsx = sc_sx;
drawsy = sc_sy;
drawx += wig_psx.get(seed + life);
drawy += wig_psy.get(seed + life);
drawrot += wig_rot.get(seed + life);
drawsx += wig_scy.get(seed + life);
drawsy += wig_scy.get(seed + life);
} #endregion
2022-12-13 09:20:36 +01:00
static draw = function(exact, surf_w, surf_h) { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-13 09:20:36 +01:00
var ss = surf;
2023-10-06 11:51:11 +02:00
if(surf != noone && is_array(surf)) {
2022-12-13 09:20:36 +01:00
var ind = abs(round((life_total - life) * anim_speed));
var len = array_length(surf);
switch(anim_end) {
case ANIM_END_ACTION.loop:
ss = surf[safe_mod(ind, len)];
break;
case ANIM_END_ACTION.pingpong:
var ping = safe_mod(ind, (len - 1) * 2 + 1);
ss = surf[ping >= len? (len - 1) * 2 - ping : ping];
break;
case ANIM_END_ACTION.destroy:
if(ind >= len) return;
else ss = surf[ind];
break;
}
}
2023-09-26 14:35:25 +02:00
var surface = is_instanceof(ss, SurfaceAtlas)? ss.getSurface() : node.surface_cache[$ ss];
2023-10-06 11:51:11 +02:00
2023-09-26 14:35:25 +02:00
if(!is_surface(surface)) return;
2022-12-13 09:20:36 +01:00
2023-02-23 07:02:19 +01:00
var lifeRat = 1 - life / life_total;
var scCurve = sct.get(lifeRat);
scx = drawsx * scCurve;
scy = drawsy * scCurve;
2023-01-17 08:11:55 +01:00
2022-12-13 09:20:36 +01:00
var _xx, _yy;
2023-09-26 14:35:25 +02:00
var s_w = surface_get_width_safe(surface) * scx;
var s_h = surface_get_height_safe(surface) * scy;
2022-12-13 09:20:36 +01:00
2023-10-06 11:51:11 +02:00
var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot);
_xx = drawx + _pp[0];
_yy = drawy + _pp[1];
2022-12-13 09:20:36 +01:00
if(exact) {
_xx = round(_xx);
_yy = round(_yy);
}
2023-01-17 08:11:55 +01:00
var x0 = _xx - s_w * 1.5;
var y0 = _yy - s_h * 1.5;
var x1 = _xx + s_w * 1.5;
var y1 = _yy + s_h * 1.5;
2023-02-23 07:02:19 +01:00
if(x0 > surf_w || y0 > surf_h || x1 < 0 || y1 < 0) return; //culling
2023-01-17 08:11:55 +01:00
2023-03-02 07:59:14 +01:00
var cc = (col == -1)? c_white : col.eval(lifeRat);
2023-02-23 07:02:19 +01:00
if(blend != c_white) cc = colorMultiply(blend, cc);
alp_draw = alp * alp_fade.get(lifeRat);
draw_surface_ext_safe(surface, _xx, _yy, scx, scy, drawrot, cc, alp_draw);
} #endregion
2022-12-13 09:20:36 +01:00
static getPivot = function() { #region
2023-10-06 11:51:11 +02:00
gml_pragma("forceinline");
2022-12-13 09:20:36 +01:00
2023-10-06 11:51:11 +02:00
return [x, y];
} #endregion
2022-12-13 09:20:36 +01:00
}
2023-03-28 06:58:28 +02:00
#region helper
#macro UPDATE_PART_FORWARD static updateParticleForward = function() { \
var pt = outputs[| 0]; \
for( var i = 0; i < ds_list_size(pt.value_to); i++ ) { \
var _n = pt.value_to[| i]; \
if(_n.value_from != pt) continue; \
\
if(variable_struct_exists(_n.node, "updateParticleForward")) \
_n.node.updateParticleForward(); \
} \
}
#endregion