lasers: prototype a better interface for position rules
This commit is contained in:
parent
e3a4e9065e
commit
daa1b38987
14 changed files with 376 additions and 137 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
lasers_src = files(
|
||||
'laser.c',
|
||||
'draw.c',
|
||||
'internal.c',
|
||||
'laser.c',
|
||||
'rules.c',
|
||||
)
|
||||
|
|
211
src/lasers/rules.c
Normal file
211
src/lasers/rules.c
Normal file
|
@ -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 <laochailan@web.de>.
|
||||
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
||||
*/
|
||||
|
||||
#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));
|
||||
}
|
||||
|
99
src/lasers/rules.h
Normal file
99
src/lasers/rules.h
Normal file
|
@ -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 <laochailan@web.de>.
|
||||
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
||||
*/
|
||||
|
||||
#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); \
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue