taisei/src/stages/stage3/nonspells/boss_nonspells.c
2024-05-17 14:11:48 +02:00

103 lines
2.3 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 "nonspells.h"
TASK(slave, { BoxedBoss boss; real rot_speed; real rot_initial; int level; }) {
Boss *boss = TASK_BIND(ARGS.boss);
WriggleSlave *slave = stage3_host_wriggle_slave(boss->pos);
INVOKE_SUBTASK(wriggle_slave_follow,
.slave = ENT_BOX(slave),
.boss = ENT_BOX(boss),
.rot_speed = ARGS.rot_speed,
.rot_initial = ARGS.rot_initial
);
int delay = difficulty_value(9, 8, 7, 6);
if(ARGS.level > 2) {
delay += 4;
}
WAIT(1);
for(int t = 0;; t += WAIT(delay)) {
play_sfx("shot1");
cmplx aim = cnormalize(boss->pos - slave->pos);
if(aim == 0) {
continue;
}
PROJECTILE(
.proto = pp_rice,
.pos = slave->pos,
.color = RGB(0.7, 0.2, 0.1),
.move = move_linear(3 * aim),
);
if(!(t % (delay * 2)) || ARGS.level > 1) {
PROJECTILE(
.proto = pp_thickrice,
.pos = slave->pos,
.color = RGB(0.7, 0.7, 0.1),
.move = move_linear(2.5 * aim),
);
}
if(ARGS.level > 2) {
PROJECTILE(
.proto = pp_wave,
.pos = slave->pos,
.color = RGB(0.3, 0.1 + 0.6 * psin(t / 25.0), 0.7),
.move = move_linear(2 * aim),
);
}
}
}
static void wriggle_nonspell_common(Boss *boss, int level) {
int n = difficulty_value(4, 5, 6, 7);
for(int i = 0; i < n; ++i) {
INVOKE_SUBTASK(slave, ENT_BOX(boss), 1/70.0, i*M_TAU/n, level);
INVOKE_SUBTASK(slave, ENT_BOX(boss), -1/70.0, -i*M_TAU/n, level);
}
Rect wander_bounds = viewport_bounds(120);
wander_bounds.bottom = 180 + 20 * level;
real wander_dist = 60 + 10 * level;
boss->move = move_towards(0, boss->pos, 0.02);
for(;;) {
WAIT(120);
boss->move.attraction_point = common_wander(boss->pos, wander_dist, wander_bounds);
WAIT(120);
}
STALL;
}
DEFINE_EXTERN_TASK(stage3_boss_nonspell_1) {
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
BEGIN_BOSS_ATTACK(&ARGS);
wriggle_nonspell_common(boss, 1);
}
DEFINE_EXTERN_TASK(stage3_boss_nonspell_2) {
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
BEGIN_BOSS_ATTACK(&ARGS);
wriggle_nonspell_common(boss, 2);
}
DEFINE_EXTERN_TASK(stage3_boss_nonspell_3) {
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
BEGIN_BOSS_ATTACK(&ARGS);
wriggle_nonspell_common(boss, 3);
}