stage3: port moonlight rocket

This commit is contained in:
Andrei Alexeyev 2021-02-04 08:53:00 +02:00
parent 859592a89b
commit 990489e960
No known key found for this signature in database
GPG key ID: 72D26128040B9690
3 changed files with 125 additions and 5 deletions

View file

@ -14,12 +14,129 @@
#include "common_tasks.h"
#include "global.h"
TASK(cancel_event, { CoEvent *event; }) {
coevent_cancel(ARGS.event);
}
TASK(laser_bullet, { BoxedProjectile p; BoxedLaser l; CoEvent *event; int event_time; }) {
Laser *l = NOT_NULL(ENT_UNBOX(ARGS.l));
if(ARGS.event) {
INVOKE_TASK_AFTER(&TASK_EVENTS(THIS_TASK)->finished, cancel_event, ARGS.event);
}
Projectile *p = TASK_BIND(ARGS.p);
for(int t = 0; (l = ENT_UNBOX(ARGS.l)); ++t, YIELD) {
p->pos = l->prule(l, t);
if(t == 0) {
p->prevpos = p->pos;
}
if(t == ARGS.event_time && ARGS.event) {
coevent_signal(ARGS.event);
}
}
kill_projectile(p);
}
TASK(rocket, { BoxedBoss boss; cmplx pos; cmplx dir; Color color; real phase; real accel_rate; }) {
Boss *boss = TASK_BIND(ARGS.boss);
real dt = 60;
Laser *l = create_lasercurve4c(
ARGS.pos, dt, dt, &ARGS.color, las_sine_expanding, 2.5*ARGS.dir, M_PI/20, 0.2, ARGS.phase
);
Projectile *p = PROJECTILE(
.proto = pp_ball,
.color = RGB(1.0, 0.4, 0.6),
.flags = PFLAG_NOMOVE,
);
COEVENTS_ARRAY(phase2, explosion) events;
TASK_HOST_EVENTS(events);
INVOKE_TASK(laser_bullet, ENT_BOX(p), ENT_BOX(l), &events.phase2, dt);
WAIT_EVENT_OR_DIE(&events.phase2);
play_sfx("redirect");
// if we get here, p must be still alive and valid
cmplx dist = global.plr.pos - p->pos;
cmplx accel = ARGS.accel_rate * cnormalize(dist);
dt = sqrt(2 * cabs(dist) / ARGS.accel_rate);
l = create_lasercurve2c(p->pos, dt, dt, RGBA(0.4, 0.9, 1.0, 0.0), las_accel, 0, accel);
l->width = 15;
INVOKE_TASK(laser_bullet, ENT_BOX(p), ENT_BOX(l), &events.explosion, dt);
WAIT_EVENT_OR_DIE(&events.explosion);
// if we get here, p must be still alive and valid
int cnt = 22;
real rot = (global.frames - NOT_NULL(boss->current)->starttime) * 0.0037 * global.diff;
Color *c = HSLA(fmod(rot, M_TAU) / (M_TAU), 1.0, 0.5, 0);
real boost = difficulty_value(4, 6, 8, 10);
for(int i = 0; i < cnt; ++i) {
real f = (real)i/cnt;
cmplx dir = cdir(M_TAU * f + rot);
cmplx v = (1.0 + psin(M_TAU * 9 * f)) * dir;
PROJECTILE(
.proto = pp_thickrice,
.pos = p->pos,
.color = c,
.move = move_asymptotic_simple(v, boost),
);
}
real to = rng_range(30, 35);
real scale = rng_range(2, 2.5);
PARTICLE(
.proto = pp_blast,
.pos = p->pos,
.color = c,
.timeout = to,
.draw_rule = pdraw_timeout_scalefade(0.01, scale, 1, 0),
.angle = rng_angle(),
);
// FIXME: better sound
play_sound("enemydeath");
play_sound("shot1");
play_sound("shot1_special");
kill_projectile(p);
}
TASK(rocket_slave, { BoxedBoss boss; real rot_speed; real rot_initial; }) {
Boss *boss = TASK_BIND(ARGS.boss);
cmplx dir;
WriggleSlave *slave = stage3_host_wriggle_slave(boss->pos);
INVOKE_TASK(wriggle_slave_damage_trail, ENT_BOX(slave));
INVOKE_TASK(wriggle_slave_follow, ENT_BOX(slave), ENT_BOX(boss), ARGS.rot_speed, ARGS.rot_initial);
STALL;
INVOKE_SUBTASK(wriggle_slave_damage_trail, ENT_BOX(slave));
INVOKE_SUBTASK(wriggle_slave_follow,
.slave = ENT_BOX(slave),
.boss = ENT_BOX(boss),
.rot_speed = ARGS.rot_speed,
.rot_initial = ARGS.rot_initial,
.out_dir = &dir
);
int rperiod = difficulty_value(220, 200, 180, 160);
real laccel = difficulty_value(0.15, 0.2, 0.25, 0.3);
WAIT(rperiod/2);
for(;;WAIT(rperiod)) {
play_sound("laser1");
INVOKE_TASK(rocket, ENT_BOX(boss), slave->pos, dir, *RGBA(1.0, 1.0, 0.5, 0.0), 0, laccel);
INVOKE_TASK(rocket, ENT_BOX(boss), slave->pos, dir, *RGBA(0.5, 1.0, 0.5, 0.0), M_PI, laccel);
}
}
DEFINE_EXTERN_TASK(stage3_spell_moonlight_rocket) {
@ -35,5 +152,6 @@ DEFINE_EXTERN_TASK(stage3_spell_moonlight_rocket) {
}
}
// keep subtasks alive
STALL;
}

View file

@ -136,9 +136,10 @@ DEFINE_EXTERN_TASK(wriggle_slave_follow) {
for(;(boss = ENT_UNBOX(ARGS.boss)); YIELD) {
real t = global.frames - slave->spawn_time;
move.attraction_point = boss->pos + 100 * sin(t / 100) * dir;
// log_debug("%f %f", creal(move.attraction_point), cimag(move.attraction_point));
move_update(&slave->pos, &move);
// slave->pos = move.attraction_point;
if(ARGS.out_dir) {
*ARGS.out_dir = dir;
}
dir *= r;
}
}

View file

@ -39,4 +39,5 @@ DECLARE_EXTERN_TASK(wriggle_slave_follow, {
BoxedBoss boss;
real rot_speed;
real rot_initial;
cmplx *out_dir;
});