some WIP charge effects
This commit is contained in:
parent
488aa71acb
commit
cd6004dde0
4 changed files with 186 additions and 18 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "common_tasks.h"
|
||||
#include "random.h"
|
||||
#include "util/glm.h"
|
||||
|
||||
DEFINE_EXTERN_TASK(common_drop_items) {
|
||||
cmplx p = *ARGS.pos;
|
||||
|
@ -54,6 +55,105 @@ DEFINE_EXTERN_TASK(common_start_bgm) {
|
|||
stage_start_bgm(ARGS.bgm);
|
||||
}
|
||||
|
||||
static Projectile *spawn_charge_particle(cmplx target, real dist, const Color *clr) {
|
||||
cmplx pos = target + rng_dir() * dist;
|
||||
|
||||
return PARTICLE(
|
||||
.sprite = "graze",
|
||||
.color = clr,
|
||||
.pos = pos,
|
||||
.draw_rule = pdraw_timeout_scalefade(2, 0.1*(1+I), 0, 1),
|
||||
.move = move_towards(target, rng_range(0.12, 0.16)),
|
||||
.timeout = 30,
|
||||
// .scale = 0.5+1.5*I,
|
||||
.flags = PFLAG_NOREFLECT,
|
||||
.layer = LAYER_PARTICLE_HIGH,
|
||||
);
|
||||
}
|
||||
|
||||
static void randomize_hue(Color *clr, float r) {
|
||||
float h, s, l, a = clr->a;
|
||||
color_get_hsl(clr, &h, &s, &l);
|
||||
h += rng_sreal() * r;
|
||||
*clr = *HSLA(h, s, l, a);
|
||||
}
|
||||
|
||||
DEFINE_EXTERN_TASK(common_charge) {
|
||||
real dist = 256;
|
||||
int delay = 3;
|
||||
int maxtime = ARGS.time;
|
||||
real rayfactor = 1.0 / (real)maxtime;
|
||||
float hue_rand = 0.02;
|
||||
|
||||
Color local_color;
|
||||
|
||||
cmplx anchor_null = 0;
|
||||
cmplx pos_offset = ARGS.pos;
|
||||
const cmplx *pos_anchor = ARGS.anchor;
|
||||
if(!pos_anchor) {
|
||||
pos_anchor = &anchor_null;
|
||||
}
|
||||
|
||||
const Color *p_color = ARGS.color_ref;
|
||||
if(!p_color) {
|
||||
assert(ARGS.color != NULL);
|
||||
local_color = *ARGS.color;
|
||||
p_color = &local_color;
|
||||
}
|
||||
|
||||
if(ARGS.bind_to_entity.ent) {
|
||||
TASK_BIND(ARGS.bind_to_entity);
|
||||
}
|
||||
|
||||
for(int i = 0; i < maxtime;) {
|
||||
cmplx pos = *pos_anchor + pos_offset;
|
||||
int stage = (5 * i) / maxtime;
|
||||
real sdist = dist * glm_ease_quad_out((stage + 1) / 6.0);
|
||||
|
||||
for(int j = 0; j < stage + 1; ++j) {
|
||||
Color color = *p_color;
|
||||
randomize_hue(&color, hue_rand);
|
||||
color_lerp(&color, RGBA(1, 1, 1, 0), rng_real() * 0.2);
|
||||
spawn_charge_particle(pos, sdist * (1 + 0.1 * rng_sreal()), &color);
|
||||
color_mul_scalar(&color, 0.2);
|
||||
}
|
||||
|
||||
Color color = *p_color;
|
||||
randomize_hue(&color, hue_rand);
|
||||
color_lerp(&color, RGBA(1, 1, 1, 0), rng_real() * 0.2);
|
||||
color_mul_scalar(&color, 0.5);
|
||||
|
||||
PARTICLE(
|
||||
.sprite = "blast_huge_rays",
|
||||
.color = &color,
|
||||
.pos = pos,
|
||||
.draw_rule = pdraw_timeout_scalefade(0, 1, 1, 0),
|
||||
.timeout = 30,
|
||||
.flags = PFLAG_NOREFLECT,
|
||||
.scale = glm_ease_bounce_out(rayfactor * (i + 1)),
|
||||
.angle = rng_angle(),
|
||||
.layer = LAYER_PARTICLE_HIGH,
|
||||
);
|
||||
|
||||
i += WAIT(delay);
|
||||
}
|
||||
|
||||
local_color = *p_color;
|
||||
randomize_hue(&local_color, hue_rand);
|
||||
color_mul_scalar(&local_color, 2.0);
|
||||
|
||||
PARTICLE(
|
||||
.sprite = "blast_huge_halo",
|
||||
.color = &local_color,
|
||||
.pos = *pos_anchor + pos_offset,
|
||||
.draw_rule = pdraw_timeout_scalefade(0, 2, 1, 0),
|
||||
.timeout = 30,
|
||||
.flags = PFLAG_NOREFLECT,
|
||||
.angle = rng_angle(),
|
||||
.layer = LAYER_PARTICLE_HIGH,
|
||||
);
|
||||
}
|
||||
|
||||
cmplx common_wander(cmplx origin, double dist, Rect bounds) {
|
||||
int attempts = 32;
|
||||
double angle;
|
||||
|
|
|
@ -42,6 +42,18 @@ DECLARE_EXTERN_TASK(
|
|||
{ const char *bgm; }
|
||||
);
|
||||
|
||||
DECLARE_EXTERN_TASK(
|
||||
common_charge,
|
||||
{
|
||||
cmplx pos;
|
||||
const Color *color;
|
||||
int time;
|
||||
BoxedEntity bind_to_entity;
|
||||
const cmplx *anchor;
|
||||
const Color *color_ref;
|
||||
}
|
||||
);
|
||||
|
||||
void common_move_loop(cmplx *restrict pos, MoveParams *restrict mp);
|
||||
|
||||
INLINE Rect viewport_bounds(double margin) {
|
||||
|
|
|
@ -156,15 +156,26 @@ TASK(punching_bag, NO_ARGS) {
|
|||
.power = 3,
|
||||
.points = 5,
|
||||
});
|
||||
|
||||
for(;;) {
|
||||
INVOKE_TASK(common_charge,
|
||||
.pos = e->pos,
|
||||
.color = RGBA(1, 0, 0, 0),
|
||||
.time = 60
|
||||
);
|
||||
WAIT(80);
|
||||
}
|
||||
}
|
||||
|
||||
TASK(stage_main, NO_ARGS) {
|
||||
YIELD;
|
||||
|
||||
/*
|
||||
WAIT(30);
|
||||
log_debug("test 1! %i", global.timer);
|
||||
WAIT(60);
|
||||
log_debug("test 2! %i", global.timer);
|
||||
*/
|
||||
|
||||
INVOKE_TASK(punching_bag);
|
||||
return;
|
||||
|
@ -177,9 +188,26 @@ TASK(stage_main, NO_ARGS) {
|
|||
}
|
||||
|
||||
static void cotest_begin(void) {
|
||||
corotest_procs.shader_rules = stage1_procs.shader_rules;
|
||||
stage1_procs.begin();
|
||||
INVOKE_TASK(stage_main);
|
||||
}
|
||||
|
||||
static void cotest_update(void) {
|
||||
stage1_procs.update();
|
||||
}
|
||||
|
||||
static void cotest_end(void) {
|
||||
stage1_procs.end();
|
||||
}
|
||||
|
||||
static void cotest_draw(void) {
|
||||
stage1_procs.draw();
|
||||
}
|
||||
|
||||
StageProcs corotest_procs = {
|
||||
.begin = cotest_begin,
|
||||
.end = cotest_end,
|
||||
.update = cotest_update,
|
||||
.draw = cotest_draw,
|
||||
};
|
||||
|
|
|
@ -1362,11 +1362,20 @@ TASK_WITH_INTERFACE(icy_storm, BossAttack) {
|
|||
int size_oscillation = 3;
|
||||
int size_max = size_base + size_oscillation;
|
||||
int burst_interval = difficulty_value(120, 80, 80, 80);
|
||||
int charge_time = 60;
|
||||
burst_interval -= charge_time;
|
||||
|
||||
int flakes_limit = flakes_per_burst * snowflake_bullet_limit(size_max);
|
||||
DECLARE_ENT_ARRAY(Projectile, snowflake_projs, flakes_limit);
|
||||
|
||||
for(int burst = 0;; ++burst) {
|
||||
aniplayer_queue(&boss->ani, "(9)", 0);
|
||||
play_sound("charge_generic");
|
||||
INVOKE_TASK(common_charge, boss->pos, RGBA(0, 0.5, 1.0, 0.0), charge_time);
|
||||
WAIT(charge_time);
|
||||
play_sound("shot_special1");
|
||||
aniplayer_queue(&boss->ani, "main", 0);
|
||||
|
||||
double angle_ofs = carg(global.plr.pos - boss->pos);
|
||||
int size = size_base + size_oscillation * sin(burst * 2.21);
|
||||
|
||||
|
@ -1394,6 +1403,26 @@ TASK_WITH_INTERFACE(icy_storm, BossAttack) {
|
|||
}
|
||||
}
|
||||
|
||||
TASK(move_frozen, { BoxedProjectileArray *parray; }) {
|
||||
DECLARE_ENT_ARRAY(Projectile, projs, ARGS.parray->size);
|
||||
ENT_ARRAY_FOREACH(ARGS.parray, Projectile *p, {
|
||||
ENT_ARRAY_ADD(&projs, p);
|
||||
});
|
||||
|
||||
ENT_ARRAY_FOREACH(&projs, Projectile *p, {
|
||||
p->color = *RGB(0.9, 0.9, 0.9);
|
||||
p->move.retention = 1 + 0.002 * global.diff * rng_f64();
|
||||
p->move.velocity = 2 * rng_dir();
|
||||
spawn_stain(p->pos, p->angle, 30);
|
||||
spawn_projectile_highlight_effect(p);
|
||||
play_sound_ex("shot2", 0, false);
|
||||
|
||||
if(rng_chance(0.4)) {
|
||||
YIELD;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DEFINE_EXTERN_TASK(stage1_spell_perfect_freeze) {
|
||||
Boss *boss = INIT_BOSS_ATTACK();
|
||||
BEGIN_BOSS_ATTACK();
|
||||
|
@ -1401,12 +1430,15 @@ DEFINE_EXTERN_TASK(stage1_spell_perfect_freeze) {
|
|||
for(int run = 1;;run++) {
|
||||
boss->move = move_towards(VIEWPORT_W/2.0 + 100.0*I, 0.04);
|
||||
|
||||
INVOKE_TASK(common_charge, 0, RGBA(1.0, 0.5, 0.0, 0), 40, .anchor = &boss->pos);
|
||||
WAIT(40);
|
||||
play_sound("shot_special1");
|
||||
|
||||
int n = global.diff;
|
||||
int nfrog = n*60;
|
||||
|
||||
DECLARE_ENT_ARRAY(Projectile, projs, nfrog);
|
||||
|
||||
WAIT(20);
|
||||
for(int i = 0; i < nfrog/n; i++) {
|
||||
play_loop("shot1_loop");
|
||||
|
||||
|
@ -1442,26 +1474,22 @@ DEFINE_EXTERN_TASK(stage1_spell_perfect_freeze) {
|
|||
});
|
||||
|
||||
WAIT(60);
|
||||
|
||||
double dir = rng_sign();
|
||||
boss->move = (MoveParams){ .velocity = dir*2.7+I, .retention = 0.99, .acceleration = -dir*0.017 };
|
||||
|
||||
aniplayer_queue(&boss->ani,"(9)",0);
|
||||
int charge_time = difficulty_value(85, 80, 75, 70);
|
||||
aniplayer_queue(&boss->ani, "(9)", 0);
|
||||
|
||||
play_sound("charge_generic");
|
||||
INVOKE_TASK(common_charge, +60, RGBA(0.3, 0.4, 0.9, 0), charge_time, .anchor = &boss->pos);
|
||||
INVOKE_TASK(common_charge, -60, RGBA(0.3, 0.4, 0.9, 0), charge_time, .anchor = &boss->pos);
|
||||
WAIT(charge_time);
|
||||
play_sound("shot_special1");
|
||||
|
||||
INVOKE_SUBTASK_DELAYED(120, move_frozen, &projs);
|
||||
|
||||
int d = max(0, global.diff - D_Normal);
|
||||
WAIT(60-5*global.diff);
|
||||
|
||||
ENT_ARRAY_FOREACH(&projs, Projectile *p, {
|
||||
p->color = *RGB(0.9, 0.9, 0.9);
|
||||
p->move.retention = 1 + 0.002 * global.diff * rng_f64();
|
||||
p->move.velocity = 2 * rng_dir();
|
||||
spawn_stain(p->pos, p->angle, 30);
|
||||
spawn_projectile_highlight_effect(p);
|
||||
play_sound_ex("shot2", 0, false);
|
||||
|
||||
if(rng_chance(0.4)) {
|
||||
YIELD;
|
||||
}
|
||||
});
|
||||
|
||||
for(int i = 0; i < 30+10*d; i++) {
|
||||
play_loop("shot1_loop");
|
||||
float r1, r2;
|
||||
|
@ -1489,7 +1517,7 @@ DEFINE_EXTERN_TASK(stage1_spell_perfect_freeze) {
|
|||
}
|
||||
aniplayer_queue(&boss->ani,"main",0);
|
||||
|
||||
WAIT(40-5*global.diff);
|
||||
WAIT(20-5*global.diff);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue