taisei/src/stages/stage1/spells/crystal_rain.c
2024-05-17 14:11:48 +02:00

88 lines
2.1 KiB
C

/*
* This software is licensed under the terms of the MIT License.
* See COPYING for further information.
* ---
* Copyright (c) 2011-2024, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2024, Andrei Alexeyev <akari@taisei-project.org>.
*/
#include "spells.h"
TASK(crystal_rain_drops) {
const int nshots = difficulty_value(1, 2, 4, 5);
const real accel_rate = difficulty_value(0.001, 0.001, 0.01, 0.01);
for(;;) {
play_sfx("shot2");
for(int i = 0; i < nshots; ++i) {
RNG_ARRAY(rng, 2);
cmplx org = vrng_range(rng[0], 0, VIEWPORT_W);
cmplx aim = cnormalize(global.plr.pos - org);
PROJECTILE(
.proto = pp_crystal,
.pos = org,
.color = RGB(0.2, 0.2, 0.4),
.move = move_accelerated(I, accel_rate * aim),
);
}
WAIT(10);
}
}
TASK(crystal_rain_cirno_shoot, { BoxedBoss boss; int charge_time; }) {
Boss *boss = TASK_BIND(ARGS.boss);
cmplx shot_ofs = -60*I;
aniplayer_queue(&boss->ani, "(9)", 0);
WAIT(10);
INVOKE_SUBTASK(common_charge, shot_ofs, RGBA(0.3, 0.5, 1, 0), ARGS.charge_time,
.anchor = &boss->pos,
.sound = COMMON_CHARGE_SOUNDS
);
WAIT(ARGS.charge_time);
int interval = difficulty_value(100, 80, 50, 20);
for(int t = 0, round = 0; t < 400; ++round) {
bool odd = (global.diff > D_Normal ? (round & 1) : 0);
real n = (difficulty_value(1, 2, 6, 11) + odd)/2.0;
cmplx org = boss->pos + shot_ofs;
play_sfx("shot_special1");
for(real i = -n; i <= n; i++) {
PROJECTILE(
.proto = odd? pp_plainball : pp_bigball,
.pos = org,
.color = RGB(0.2, 0.2, 0.9),
.move = move_asymptotic_simple(2 * cdir(carg(global.plr.pos - org) + 0.3 * i), 2.3),
);
}
t += WAIT(interval);
}
aniplayer_queue(&boss->ani, "main", 0);
}
DEFINE_EXTERN_TASK(stage1_spell_crystal_rain) {
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
BEGIN_BOSS_ATTACK(&ARGS);
INVOKE_SUBTASK(crystal_rain_drops);
boss->move = move_towards_exp(boss->move.velocity, boss->pos, 0.1, 0.5);
for(;;) {
WAIT(20);
stage1_cirno_wander(boss, 80, 230);
INVOKE_SUBTASK(crystal_rain_cirno_shoot, ENT_BOX(boss), 80);
WAIT(180);
stage1_cirno_wander(boss, 40, 230);
WAIT(120);
stage1_cirno_wander(boss, 40, 230);
WAIT(180);
}
}