diff --git a/src/lasers/laser.c b/src/lasers/laser.c index 4931f88a..98d1994f 100644 --- a/src/lasers/laser.c +++ b/src/lasers/laser.c @@ -46,11 +46,7 @@ void lasers_shutdown(void) { laserintern_shutdown(); } -Laser *create_laser( - cmplx pos, float time, float deathtime, const Color *color, - LaserPosRule prule, - cmplx a0, cmplx a1, cmplx a2, cmplx a3 -) { +Laser *create_laser(cmplx pos, float time, float deathtime, const Color *color, LaserRule rule) { Laser *l = objpool_acquire(&stage_object_pools.lasers); alist_push(&global.lasers, l); @@ -59,11 +55,7 @@ Laser *create_laser( l->deathtime = deathtime; l->pos = pos; l->color = *color; - l->args[0] = a0; - l->args[1] = a1; - l->args[2] = a2; - l->args[3] = a3; - l->prule = prule; + l->rule = rule; l->width = 10; l->width_exponent = 1.0; l->speed = 1; @@ -73,7 +65,7 @@ Laser *create_laser( l->ent.draw_func = laserdraw_ent_drawfunc; ent_register(&l->ent, ENT_TYPE_ID(Laser)); - l->prule(l, EVENT_BIRTH); + laser_pos_at(l, EVENT_BIRTH); return l; } @@ -90,7 +82,7 @@ Laser *create_laserline_ab(cmplx a, cmplx b, float width, float charge, float du // This value works well for the default exponent (1.0), but may need to be adjusted for other // values. 0 exponent can get away with 1 sample, because the width is then constant. float timespan = 4; - Laser *l = create_laser(0, timespan, dur, clr, las_linear, 0, 0, 0, 0); + Laser *l = create_laser(0, timespan, dur, clr, laser_rule_linear(0)); laserline_set_ab(l, a, b); INVOKE_TASK(laser_charge, .laser = ENT_BOX(l), @@ -101,8 +93,9 @@ Laser *create_laserline_ab(cmplx a, cmplx b, float width, float charge, float du } void laserline_set_ab(Laser *l, cmplx a, cmplx b) { + auto rd = NOT_NULL(laser_get_ruledata_linear(l)); + rd->velocity = (b - a) / l->timespan; l->pos = a; - l->args[0] = (b - a) / l->timespan; } void laserline_set_posdir(Laser *l, cmplx pos, cmplx dir) { @@ -231,7 +224,7 @@ static int quantize_laser(Laser *l) { // Begin constructing at t0 // WARNING: these must be double precision to prevent cross-platform replay desync cmplx a, b; - a = l->prule(l, t0); + a = laser_pos_at(l, t0); // Width value of the last included sample // Initialized to the width at t0 @@ -241,7 +234,7 @@ static int quantize_laser(Laser *l) { t += sp.time_step; // Vector from A to B of the last included segment, and its squared length. - cmplxf v0 = a - l->prule(l, t0 - sp.time_step); + cmplxf v0 = a - laser_pos_at(l, t0 - sp.time_step); float v0_abs2 = cabs2f(v0); float viewmargin = l->width * 0.5f; @@ -256,7 +249,7 @@ static int quantize_laser(Laser *l) { bottom_right.as_cmplx = a; for(uint i = 1; i < sp.num_samples; ++i, t += sp.time_step) { - b = l->prule(l, t); + b = laser_pos_at(l, t); if(i < sp.num_samples - 1 && (t - t0) < thres_temporal) { cmplxf v1 = b - a; @@ -672,89 +665,6 @@ bool laser_intersects_circle(Laser *l, Circle circle) { return laser_intersects_ellipse(l, ellipse); } -cmplx las_linear(Laser *l, float t) { - if(t == EVENT_BIRTH) { - return 0; - } - - return l->pos + l->args[0]*t; -} - -cmplx las_accel(Laser *l, float t) { - if(t == EVENT_BIRTH) { - return 0; - } - - return l->pos + l->args[0]*t + 0.5*l->args[1]*t*t; -} - -cmplx las_sine(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase - // this is actually shaped like a sine wave - - if(t == EVENT_BIRTH) { - return 0; - } - - cmplx line_vel = l->args[0]; - cmplx line_dir = line_vel / cabs(line_vel); - cmplx line_normal = im(line_dir) - I*re(line_dir); - cmplx sine_amp = l->args[1]; - real sine_freq = re(l->args[2]); - real sine_phase = re(l->args[3]); - - cmplx sine_ofs = line_normal * sine_amp * sin(sine_freq * t + sine_phase); - return l->pos + t * line_vel + sine_ofs; -} - -cmplx las_sine_expanding(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase - - if(t == EVENT_BIRTH) { - return 0; - } - - cmplx velocity = l->args[0]; - real amplitude = re(l->args[1]); - real frequency = re(l->args[2]); - real phase = re(l->args[3]); - - real angle = carg(velocity); - real speed = cabs(velocity); - - real s = (frequency * t + phase); - return l->pos + cdir(angle + amplitude * sin(s)) * t * speed; -} - -cmplx las_turning(Laser *l, float t) { // [0] = vel0; [1] = vel1; [2] r: turn begin time, i: turn end time - if(t == EVENT_BIRTH) { - return 0; - } - - cmplx v0 = l->args[0]; - cmplx v1 = l->args[1]; - float begin = re(l->args[2]); - float end = im(l->args[2]); - - float a = clamp((t - begin) / (end - begin), 0, 1); - a = 1.0 - (0.5 + 0.5 * cos(a * M_PI)); - a = 1.0 - pow(1.0 - a, 2); - - cmplx v = v1 * a + v0 * (1 - a); - - return l->pos + v * t; -} - -cmplx las_circle(Laser *l, float t) { - if(t == EVENT_BIRTH) { - return 0; - } - - real turn_speed = re(l->args[0]); - real time_ofs = im(l->args[0]); - real radius = re(l->args[1]); - - return l->pos + radius * cdir(turn_speed * (t + time_ofs)); -} - void laser_charge(Laser *l, int t, float charge, float width) { float new_width; diff --git a/src/lasers/laser.h b/src/lasers/laser.h index 7f3df5b0..74766d03 100644 --- a/src/lasers/laser.h +++ b/src/lasers/laser.h @@ -16,15 +16,30 @@ #include "resource/shader_program.h" #include "entity.h" -typedef LIST_ANCHOR(Laser) LaserList; +typedef cmplx LaserRuleFunc(Laser *p, real t, void *ruledata); -typedef cmplx (*LaserPosRule)(Laser* l, float time); +typedef struct LaserRule { + LaserRuleFunc *func; + alignas(cmplx) char data[sizeof(cmplx) * 5]; +} LaserRule; + +typedef cmplx (*LegacyLaserPosRule)(Laser *l, float time); +typedef LegacyLaserPosRule LaserPosRule + attr_deprecated("For compatibility with legacy rules"); + +typedef LIST_ANCHOR(Laser) LaserList; DEFINE_ENTITY_TYPE(Laser, { cmplx pos; - cmplx args[4]; - LaserPosRule prule; + union { + LaserRule rule; + struct { + char _padding[offsetof(LaserRule, data)]; + cmplx args[(sizeof(LaserRule) - offsetof(LaserRule, data)) / sizeof(cmplx)] + attr_deprecated("For compatibility with legacy rules"); + }; + }; struct { int segments_ofs; @@ -50,10 +65,14 @@ DEFINE_ENTITY_TYPE(Laser, { uchar collision_active : 1; }); -#define create_lasercurve1c(p, time, deathtime, clr, rule, a0) create_laser(p, time, deathtime, clr, rule, a0, 0, 0, 0) -#define create_lasercurve2c(p, time, deathtime, clr, rule, a0, a1) create_laser(p, time, deathtime, clr, rule, a0, a1, 0, 0) -#define create_lasercurve3c(p, time, deathtime, clr, rule, a0, a1, a2) create_laser(p, time, deathtime, clr, rule, a0, a1, a2, 0) -#define create_lasercurve4c(p, time, deathtime, clr, rule, a0, a1, a2, a3) create_laser(p, time, deathtime, clr, rule, a0, a1, a2, a3) +#define create_lasercurve1c(p, time, deathtime, clr, rule, a0) \ + create_laser(p, time, deathtime, clr, laser_rule_compat(rule, a0, 0, 0, 0)) +#define create_lasercurve2c(p, time, deathtime, clr, rule, a0, a1) \ + create_laser(p, time, deathtime, clr, laser_rule_compat(rule, a0, a1, 0, 0)) +#define create_lasercurve3c(p, time, deathtime, clr, rule, a0, a1, a2) \ + create_laser(p, time, deathtime, clr, laser_rule_compat(rule, a0, a1, a2, 0)) +#define create_lasercurve4c(p, time, deathtime, clr, rule, a0, a1, a2, a3) \ + create_laser(p, time, deathtime, clr, laser_rule_compat(rule, a0, a1, a2, a3)) void lasers_init(void); void lasers_shutdown(void); @@ -66,19 +85,12 @@ Laser *create_laserline_ab(cmplx a, cmplx b, float width, float charge, float du void laserline_set_ab(Laser *l, cmplx a, cmplx b); void laserline_set_posdir(Laser *l, cmplx pos, cmplx dir); -Laser *create_laser(cmplx pos, float time, float deathtime, const Color *color, LaserPosRule prule, cmplx a0, cmplx a1, cmplx a2, cmplx a3); +Laser *create_laser(cmplx pos, float time, float deathtime, const Color *color, LaserRule rule); bool laser_is_active(Laser *l); bool laser_is_clearable(Laser *l); bool clear_laser(Laser *l, uint flags); -cmplx las_linear(Laser *l, float t); -cmplx las_accel(Laser *l, float t); -cmplx las_sine(Laser *l, float t); -cmplx las_sine_expanding(Laser *l, float t); -cmplx las_turning(Laser *l, float t); -cmplx las_circle(Laser *l, float t); - void laser_make_static(Laser *l); void laser_charge(Laser *l, int t, float charge, float width); @@ -110,8 +122,14 @@ typedef struct LaserTraceSample { typedef void *(*LaserTraceFunc)(Laser *l, const LaserTraceSample *sample, void *userdata); void *laser_trace(Laser *l, real step, LaserTraceFunc trace, void *userdata); +INLINE cmplx laser_pos_at(Laser *l, real t) { + return l->rule.func(l, t, &l->rule.data); +} + DECLARE_EXTERN_TASK(laser_charge, { BoxedLaser laser; float charge_delay; float target_width; }); + +#include "rules.h" diff --git a/src/lasers/meson.build b/src/lasers/meson.build index f92a5fd6..58dc0711 100644 --- a/src/lasers/meson.build +++ b/src/lasers/meson.build @@ -1,6 +1,7 @@ lasers_src = files( - 'laser.c', 'draw.c', 'internal.c', + 'laser.c', + 'rules.c', ) diff --git a/src/lasers/rules.c b/src/lasers/rules.c new file mode 100644 index 00000000..a360661e --- /dev/null +++ b/src/lasers/rules.c @@ -0,0 +1,211 @@ +/* + * This software is licensed under the terms of the MIT License. + * See COPYING for further information. + * --- + * Copyright (c) 2011-2019, Lukas Weber . + * Copyright (c) 2012-2019, Andrei Alexeyev . +*/ + +#include "taisei.h" + +#include "rules.h" + +#include "global.h" + +static cmplx laser_rule_linear_impl(Laser *l, real t, void *ruledata) { + LaserRuleLinearData *rd = ruledata; + return l->pos + t * rd->velocity; +} + +LaserRule laser_rule_linear(cmplx velocity) { + LaserRuleLinearData rd = { + .velocity = velocity, + }; + return MAKE_LASER_RULE(laser_rule_linear_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_linear, + laser_rule_linear_impl, LaserRuleLinearData) + +static cmplx laser_rule_accelerated_impl(Laser *l, real t, void *ruledata) { + LaserRuleAcceleratedData *rd = ruledata; + return l->pos + t * (rd->velocity + t * rd->half_accel); +} + +LaserRule laser_rule_accelerated(cmplx velocity, cmplx accel) { + LaserRuleAcceleratedData rd = { + .velocity = velocity, + .half_accel = accel * 0.5, + }; + return MAKE_LASER_RULE(laser_rule_accelerated_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_accelerated, + laser_rule_accelerated_impl, LaserRuleAcceleratedData) + +static cmplx laser_rule_sine_impl(Laser *l, real t, void *ruledata) { + LaserRuleSineData *rd = ruledata; + cmplx line_vel = rd->velocity; + cmplx line_dir = line_vel / cabs(line_vel); + cmplx line_normal = im(line_dir) - I*re(line_dir); + cmplx sine_ofs = line_normal * rd->amplitude * sin(rd->frequency * t + rd->phase); + return l->pos + t * line_vel + sine_ofs; +} + +LaserRule laser_rule_sine(cmplx velocity, cmplx amplitude, real frequency, real phase) { + LaserRuleSineData rd = { + .velocity = velocity, + .amplitude = amplitude, + .frequency = frequency, + .phase = phase, + }; + return MAKE_LASER_RULE(laser_rule_sine_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_sine, + laser_rule_sine_impl, LaserRuleSineData) + +static cmplx laser_rule_sine_expanding_impl(Laser *l, real t, void *ruledata) { + LaserRuleSineExpandingData *rd = ruledata; + real angle = carg(rd->velocity); + real speed = cabs(rd->velocity); + real s = (rd->frequency * t + rd->phase); + return l->pos + cdir(angle + rd->amplitude * sin(s)) * t * speed; +} + +LaserRule laser_rule_sine_expanding(cmplx velocity, real amplitude, real frequency, real phase) { + LaserRuleSineExpandingData rd = { + .velocity = velocity, + .amplitude = amplitude, + .frequency = frequency, + .phase = phase, + }; + return MAKE_LASER_RULE(laser_rule_sine_expanding_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_sine_expanding, + laser_rule_sine_expanding_impl, LaserRuleSineExpandingData) + +static cmplx laser_rule_arc_impl(Laser *l, real t, void *ruledata) { + LaserRuleArcData *rd = ruledata; + return l->pos + rd->radius * cdir(rd->turn_speed * (t + rd->time_ofs)); +} + +LaserRule laser_rule_arc(cmplx radius, real turnspeed, real timeofs) { + LaserRuleArcData rd = { + .radius = radius, + .turn_speed = turnspeed, + .time_ofs = timeofs, + }; + return MAKE_LASER_RULE(laser_rule_arc_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_arc, + laser_rule_arc_impl, LaserRuleArcData) + +/* + * Legacy rules for compatibility (TODO remove) + */ + +static cmplx laser_rule_compat_impl(Laser *l, real t, void *ruledata) { + LaserRuleCompatData *rd = ruledata; + return rd->oldrule(l, t); +} + +LaserRule laser_rule_compat(LegacyLaserPosRule oldrule, cmplx a0, cmplx a1, cmplx a2, cmplx a3) { + LaserRuleCompatData rd = { + .oldrule = oldrule, + .args = { a0, a1, a2, a3 }, + }; + + return MAKE_LASER_RULE(laser_rule_compat_impl, rd); +} + +IMPL_LASER_RULE_DATAGETTER(laser_get_ruledata_compat, + laser_rule_compat_impl, LaserRuleCompatData) + +DIAGNOSTIC(ignored "-Wdeprecated-declarations") + +cmplx las_linear(Laser *l, float t) { + if(t == EVENT_BIRTH) { + return 0; + } + + return l->pos + l->args[0]*t; +} + +cmplx las_accel(Laser *l, float t) { + if(t == EVENT_BIRTH) { + return 0; + } + + return l->pos + l->args[0]*t + 0.5*l->args[1]*t*t; +} + +cmplx las_sine(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase + // this is actually shaped like a sine wave + + if(t == EVENT_BIRTH) { + return 0; + } + + cmplx line_vel = l->args[0]; + cmplx line_dir = line_vel / cabs(line_vel); + cmplx line_normal = im(line_dir) - I*re(line_dir); + cmplx sine_amp = l->args[1]; + real sine_freq = re(l->args[2]); + real sine_phase = re(l->args[3]); + + cmplx sine_ofs = line_normal * sine_amp * sin(sine_freq * t + sine_phase); + return l->pos + t * line_vel + sine_ofs; +} + +cmplx las_sine_expanding(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase + + if(t == EVENT_BIRTH) { + return 0; + } + + cmplx velocity = l->args[0]; + real amplitude = re(l->args[1]); + real frequency = re(l->args[2]); + real phase = re(l->args[3]); + + real angle = carg(velocity); + real speed = cabs(velocity); + + real s = (frequency * t + phase); + return l->pos + cdir(angle + amplitude * sin(s)) * t * speed; +} + +cmplx las_turning(Laser *l, float t) { // [0] = vel0; [1] = vel1; [2] r: turn begin time, i: turn end time + if(t == EVENT_BIRTH) { + return 0; + } + + cmplx v0 = l->args[0]; + cmplx v1 = l->args[1]; + float begin = re(l->args[2]); + float end = im(l->args[2]); + + float a = clamp((t - begin) / (end - begin), 0, 1); + a = 1.0 - (0.5 + 0.5 * cos(a * M_PI)); + a = 1.0 - pow(1.0 - a, 2); + + cmplx v = v1 * a + v0 * (1 - a); + + return l->pos + v * t; +} + +cmplx las_circle(Laser *l, float t) { + if(t == EVENT_BIRTH) { + return 0; + } + + real turn_speed = re(l->args[0]); + real time_ofs = im(l->args[0]); + real radius = re(l->args[1]); + + return l->pos + radius * cdir(turn_speed * (t + time_ofs)); +} + diff --git a/src/lasers/rules.h b/src/lasers/rules.h new file mode 100644 index 00000000..557a5f35 --- /dev/null +++ b/src/lasers/rules.h @@ -0,0 +1,99 @@ +/* + * This software is licensed under the terms of the MIT License. + * See COPYING for further information. + * --- + * Copyright (c) 2011-2019, Lukas Weber . + * Copyright (c) 2012-2019, Andrei Alexeyev . +*/ + +#pragma once +#include "taisei.h" + +#include "laser.h" + +cmplx las_linear(Laser *l, float t) attr_deprecated("Use laser_rule_linear"); +cmplx las_accel(Laser *l, float t) attr_deprecated("Use laser_rule_accelerated"); +cmplx las_sine(Laser *l, float t) attr_deprecated("Use laser_rule_sine"); +cmplx las_sine_expanding(Laser *l, float t) attr_deprecated("Use laser_rule_sine_expanding"); +cmplx las_turning(Laser *l, float t) attr_deprecated("No replacement"); +cmplx las_circle(Laser *l, float t) attr_deprecated("Use laser_rule_arc"); + +extern LaserRuleFunc laser_rule_compat_adapter; + +typedef struct LaserRuleLinearData { + cmplx velocity; +} LaserRuleLinearData; + +LaserRule laser_rule_linear(cmplx velocity); +LaserRuleLinearData *laser_get_ruledata_linear(Laser *l); + +typedef struct LaserRuleAcceleratedData { + cmplx velocity; + cmplx half_accel; +} LaserRuleAcceleratedData; + +LaserRule laser_rule_accelerated(cmplx velocity, cmplx accel); +LaserRuleAcceleratedData *laser_get_ruledata_accelerated(Laser *l); + +typedef struct LaserRuleSineData { + cmplx velocity; + cmplx amplitude; + real frequency; + real phase; +} LaserRuleSineData; + +LaserRule laser_rule_sine(cmplx velocity, cmplx amplitude, real frequency, real phase); +LaserRuleSineData *laser_get_ruledata_sine(Laser *l); + +typedef struct LaserRuleSineExpandingData { + cmplx velocity; + real amplitude; + real frequency; + real phase; +} LaserRuleSineExpandingData; + +LaserRule laser_rule_sine_expanding(cmplx velocity, real amplitude, real frequency, real phase); +LaserRuleSineExpandingData *laser_get_ruledata_sine_expanding(Laser *l); + +typedef struct LaserRuleArcData { + cmplx radius; + real turn_speed; + real time_ofs; +} LaserRuleArcData; + +LaserRule laser_rule_arc(cmplx radius, real turnspeed, real timeofs); +LaserRuleArcData *laser_get_ruledata_arc(Laser *l); + +typedef struct LaserRuleCompatData { + cmplx args[4]; + LegacyLaserPosRule oldrule; +} LaserRuleCompatData; + +LaserRule laser_rule_compat(LegacyLaserPosRule oldrule, cmplx a0, cmplx a1, cmplx a2, cmplx a3) + attr_deprecated("Use the new rule format (see laser/rules.h)"); +LaserRuleCompatData *laser_get_ruledata_compat(Laser *l); + +#define MAKE_LASER_RULE(func, data) ({ \ + union { \ + LaserRule r; \ + struct { \ + LaserRuleFunc *f; \ + typeof(data) _data; \ + } src; \ + } cvt = { \ + .src.f = func, \ + .src._data = data, \ + }; \ + static_assert(sizeof(cvt) == sizeof(LaserRule)); \ + cvt.r; \ +}) + +#define GET_LASER_RULEDATA(_laser, _func, _data_type) ( \ + (_laser)->rule.func == _func \ + ? CASTPTR_ASSUME_ALIGNED(&(_laser)->rule.data, _data_type) \ + : NULL) + +#define IMPL_LASER_RULE_DATAGETTER(_getter_func, _rule_func, _data_type) \ + _data_type *_getter_func(Laser *l) { \ + return GET_LASER_RULEDATA(l, _rule_func, _data_type); \ + } diff --git a/src/stages/stage3/spells/light_singularity.c b/src/stages/stage3/spells/light_singularity.c index 14d242ca..fad50530 100644 --- a/src/stages/stage3/spells/light_singularity.c +++ b/src/stages/stage3/spells/light_singularity.c @@ -15,9 +15,9 @@ #include "global.h" TASK(singularity_laser, { cmplx pos; cmplx vel; real amp; real freq; }) { - Laser *l = TASK_BIND(create_laser(ARGS.pos, + Laser *l = TASK_BIND(create_lasercurve3c(ARGS.pos, 200, 10000, RGBA(0.0, 0.2, 1.0, 0.0), las_sine_expanding, - ARGS.vel, ARGS.amp, ARGS.freq, 0 + ARGS.vel, ARGS.amp, ARGS.freq )); laser_make_static(l); diff --git a/src/stages/stage3/spells/moonlight_rocket.c b/src/stages/stage3/spells/moonlight_rocket.c index 1288971b..d90f3184 100644 --- a/src/stages/stage3/spells/moonlight_rocket.c +++ b/src/stages/stage3/spells/moonlight_rocket.c @@ -64,7 +64,7 @@ TASK(laser_bullet, { BoxedProjectile p; BoxedLaser l; CoEvent *event; int event_ Projectile *p = TASK_BIND(ARGS.p); for(int t = 0; (l = ENT_UNBOX(ARGS.l)); ++t, YIELD) { - p->pos = l->prule(l, t); + p->pos = laser_pos_at(l, t); if(t == 0) { p->prevpos = p->pos; diff --git a/src/stages/stage4/timeline.c b/src/stages/stage4/timeline.c index 0a70ebf8..f6cb2f84 100644 --- a/src/stages/stage4/timeline.c +++ b/src/stages/stage4/timeline.c @@ -603,7 +603,7 @@ TASK(laser_pattern_fairy, { cmplx pos; cmplx dir; }) { int count = 5; real length = difficulty_value(20,30,40,50); for(int i = 0; i < count; i++) { - create_laser(e->pos, length, 200, RGBA(0.7, 1.0, 0.2, 0), las_linear, 3*ARGS.dir*cdir(M_TAU/count * i), 0, 0, 0); + create_lasercurve1c(e->pos, length, 200, RGBA(0.7, 1.0, 0.2, 0), las_linear, 3*ARGS.dir*cdir(M_TAU/count * i)); } play_sfx("laser1"); diff --git a/src/stages/stage5/timeline.c b/src/stages/stage5/timeline.c index 34cc5dfa..3744a243 100644 --- a/src/stages/stage5/timeline.c +++ b/src/stages/stage5/timeline.c @@ -678,9 +678,9 @@ TASK(lasertrap_warning, { cmplx pos; int time; real radius; }) { static Laser *laser_arc(cmplx center, real lifetime, real radius, real arcangle, real arcshift) { real a = arcangle/lifetime; - Laser *l = create_laser( + Laser *l = create_lasercurve2c( center, lifetime, lifetime, RGBA(0.5, 0.1, 1.0, 0), las_circle, - a + I*arcshift/a, radius, 0, 0 + a + I*arcshift/a, radius ); laser_make_static(l); @@ -708,11 +708,11 @@ TASK(lasertrap_arc_bullet, { BoxedLaser l; int timeout; }) { )); Laser *l = NOT_NULL(ENT_UNBOX(ARGS.l)); - p->pos = l->prule(l, 0); + p->pos = laser_pos_at(l, 0); for(;(l = ENT_UNBOX(ARGS.l)); YIELD) { p->prevpos = p->pos; - p->pos = l->prule(l, 0); + p->pos = laser_pos_at(l, 0); iku_lightning_particle(p->pos); } diff --git a/src/stages/stage6/spells/broglie.c b/src/stages/stage6/spells/broglie.c index 5670b665..955fbf49 100644 --- a/src/stages/stage6/spells/broglie.c +++ b/src/stages/stage6/spells/broglie.c @@ -22,8 +22,8 @@ TASK(broglie_particle, { BoxedLaser laser; real laser_offset; Color color; bool real speed = ARGS.fast ? 2.0 : 1.5; - cmplx pos = l->prule(l, ARGS.laser_offset); - cmplx dir = cnormalize(pos - l->prule(l, ARGS.laser_offset-0.1)); + cmplx pos = laser_pos_at(l, ARGS.laser_offset); + cmplx dir = cnormalize(pos - laser_pos_at(l, ARGS.laser_offset-0.1)); dir *= cdir(angle_ampl * sin(scatter_time * ARGS.angle_freq) * cos(2 * scatter_time * ARGS.angle_freq)); PROJECTILE( diff --git a/src/stages/stage6/spells/lhc.c b/src/stages/stage6/spells/lhc.c index a4a88222..b9bde5d2 100644 --- a/src/stages/stage6/spells/lhc.c +++ b/src/stages/stage6/spells/lhc.c @@ -21,7 +21,7 @@ static real lhc_target_height(int turn) { TASK(lhc_laser, { BoxedEllyBaryons baryons; int baryon_idx; real direction; Color color;}) { EllyBaryons *baryons = NOT_NULL(ENT_UNBOX(ARGS.baryons)); - Laser *l = TASK_BIND(create_laser(baryons->poss[ARGS.baryon_idx], 200, 300, &ARGS.color, las_linear, ARGS.direction * VIEWPORT_W * 0.005, 0, 0, 0)); + Laser *l = TASK_BIND(create_lasercurve1c(baryons->poss[ARGS.baryon_idx], 200, 300, &ARGS.color, las_linear, ARGS.direction * VIEWPORT_W * 0.005)); l->unclearable = true; INVOKE_SUBTASK(laser_charge, ENT_BOX(l), 200, 30); diff --git a/src/stages/stage6/spells/maxwell.c b/src/stages/stage6/spells/maxwell.c index 90e5a873..f9160239 100644 --- a/src/stages/stage6/spells/maxwell.c +++ b/src/stages/stage6/spells/maxwell.c @@ -26,7 +26,7 @@ static cmplx maxwell_laser(Laser *l, float t) { } TASK(maxwell_laser, { cmplx pos; cmplx dir; real phase; real phase_speed; }) { - Laser *l = TASK_BIND(create_laser(ARGS.pos, 200, 10000, RGBA(0, 0.2, 1, 0.0), maxwell_laser, ARGS.dir*VIEWPORT_H*0.005, 0, 0, 0)); + Laser *l = TASK_BIND(create_lasercurve1c(ARGS.pos, 200, 10000, RGBA(0, 0.2, 1, 0.0), maxwell_laser, ARGS.dir*VIEWPORT_H*0.005)); INVOKE_SUBTASK(laser_charge, ENT_BOX(l), .charge_delay = 200, .target_width = 15); diff --git a/src/stages/stage6/spells/ricci.c b/src/stages/stage6/spells/ricci.c index cfce8f37..a9b790f9 100644 --- a/src/stages/stage6/spells/ricci.c +++ b/src/stages/stage6/spells/ricci.c @@ -36,7 +36,7 @@ static real safe_radius(real phase) { } TASK(ricci_laser, { BoxedEllyBaryons baryons; int baryon_idx; cmplx offset; Color color; real turn_speed; real timespan; int time_offset; }) { - Laser *l = TASK_BIND(create_laser(0, ARGS.timespan, 60, &ARGS.color, las_circle, ARGS.turn_speed + I * ARGS.time_offset, 0, 0, 0)); + Laser *l = TASK_BIND(create_lasercurve1c(0, ARGS.timespan, 60, &ARGS.color, las_circle, ARGS.turn_speed + I * ARGS.time_offset)); real radius = SAFE_RADIUS_MAX * difficulty_value(0.4, 0.47, 0.53, 0.6); diff --git a/src/stages/stage6/spells/toe.c b/src/stages/stage6/spells/toe.c index 97939008..21db720a 100644 --- a/src/stages/stage6/spells/toe.c +++ b/src/stages/stage6/spells/toe.c @@ -377,20 +377,20 @@ TASK(toe_laser_respawn, { cmplx pos; cmplx vel; int type; }) { } DEFINE_TASK(toe_laser) { - Laser *l = TASK_BIND(create_laser(ARGS.pos, LASER_LENGTH, ARGS.deathtime, RGBA(1, 1, 1, 0), - toe_laser_pos, - ARGS.vel, - ARGS.type, - 0, - 0 - )); + Laser *l = TASK_BIND( + create_lasercurve2c(ARGS.pos, LASER_LENGTH, ARGS.deathtime, RGBA(1, 1, 1, 0), + toe_laser_pos, + ARGS.vel, + ARGS.type + ) + ); toe_laser_particle(l, ARGS.pos); cmplx drift = 0.2 * I; for(int t = 0;; t++) { if(t == l->deathtime - 1) { - cmplx newpos = l->prule(l, l->deathtime); + cmplx newpos = laser_pos_at(l, l->deathtime); INVOKE_TASK(toe_laser_respawn, newpos, ARGS.vel, ARGS.type); }