stage3: redesign scuttle's spell
This commit is contained in:
parent
cf8015c784
commit
736e659bab
5 changed files with 112 additions and 131 deletions
|
@ -5,9 +5,9 @@ stage3_src = files(
|
|||
'draw.c',
|
||||
'nonspells/boss_nonspells.c',
|
||||
'nonspells/midboss_nonspell_1.c',
|
||||
'spells/deadly_dance.c',
|
||||
'spells/firefly_storm.c',
|
||||
'spells/light_singularity.c',
|
||||
'spells/logic_bomb.c',
|
||||
'spells/moonlight_rocket.c',
|
||||
'spells/night_ignite.c',
|
||||
'stage3.c',
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* 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 "spells.h"
|
||||
#include "../scuttle.h"
|
||||
|
||||
#include "common_tasks.h"
|
||||
#include "global.h"
|
||||
|
||||
TASK(spawner_proj, { cmplx pos; MoveParams move; Color *color; int t; int i; }) {
|
||||
Projectile *p = TASK_BIND(PROJECTILE(
|
||||
.proto = pp_wave,
|
||||
.pos = ARGS.pos,
|
||||
.color = ARGS.color,
|
||||
.move = ARGS.move,
|
||||
));
|
||||
|
||||
int t = ARGS.t;
|
||||
int i = ARGS.i;
|
||||
|
||||
WAIT(150);
|
||||
real a = (M_PI/(5 + global.diff) * i * 2);
|
||||
|
||||
play_sfx("redirect");
|
||||
|
||||
PROJECTILE(
|
||||
.proto = rng_chance(0.5) ? pp_thickrice : pp_rice,
|
||||
.pos = p->pos,
|
||||
.color = RGB(0.3, 0.7 + 0.3 * psin(a/3.0 + t/20.0), 0.3),
|
||||
.move = move_accelerated(0, 0.005 * cdir((M_TAU * sin(a / 5.0 + t / 20.0))))
|
||||
);
|
||||
}
|
||||
|
||||
TASK(spawners, { BoxedBoss boss; real tfactor; }) {
|
||||
Boss *boss = TASK_BIND(ARGS.boss);
|
||||
int count = difficulty_value(15, 18, 21, 24);
|
||||
real tfactor = ARGS.tfactor;
|
||||
|
||||
for(int time = 0;; time += WAIT(70)) {
|
||||
real angle_ofs = rng_angle();
|
||||
play_sfx("shot_special1");
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
real a = (M_PI/(5 + global.diff) * i * 2);
|
||||
INVOKE_TASK(spawner_proj,
|
||||
.pos = boss->pos,
|
||||
.color = RGB(0.3, 0.3 + 0.7 * psin((M_PI/(5 + global.diff) * i * 2) * 3 + time/50.0), 0.3),
|
||||
.move = move_accelerated(0, 0.02 * cdir(angle_ofs + a + time/10.0)),
|
||||
.t = time * tfactor,
|
||||
.i = i,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TASK(balls, { BoxedBoss boss; }) {
|
||||
Boss *boss = TASK_BIND(ARGS.boss);
|
||||
int count = difficulty_value(2, 4, 6, 8);
|
||||
|
||||
for(int time = 0;; time += WAIT(35)) {
|
||||
real angle_ofs = rng_angle();
|
||||
play_sfx("shot1");
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
PROJECTILE(
|
||||
.proto = pp_ball,
|
||||
.pos = boss->pos,
|
||||
.color = RGB(1.0, 1.0, 0.3),
|
||||
.move = move_asymptotic_simple(
|
||||
(0.5 + 3 * psin(time + M_PI / 3 * 2 * i)) * cdir(angle_ofs + time / 20.0 + M_PI / count * i * 2),
|
||||
1.5
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TASK(limiters, { BoxedBoss boss; }) {
|
||||
Boss *boss = TASK_BIND(ARGS.boss);
|
||||
for(int time = 0;; time += WAIT(3)) {
|
||||
play_sfx_loop("shot1_loop");
|
||||
|
||||
for(int i = -1; i < 2; i += 2) {
|
||||
real c = psin(time/10.0);
|
||||
cmplx aim = cnormalize(global.plr.pos - boss->pos);
|
||||
cmplx v = 10 * (aim + (M_PI/4.0 * i * (1 - time / 2500.0)) * (1 - 0.5 * psin(time / 15.0)));
|
||||
PROJECTILE(
|
||||
.proto = pp_crystal,
|
||||
.pos = boss->pos,
|
||||
.color = RGBA_MUL_ALPHA(0.3 + c * 0.7, 0.6 - c * 0.3, 0.3, 0.7),
|
||||
.move = move_linear(v),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_EXTERN_TASK(stage3_spell_deadly_dance) {
|
||||
STAGE_BOOKMARK(dance);
|
||||
|
||||
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
|
||||
boss->move = move_from_towards(boss->pos, VIEWPORT_W/2 + VIEWPORT_H*I/2, 0.08);
|
||||
BEGIN_BOSS_ATTACK(&ARGS);
|
||||
boss->move.attraction = 0;
|
||||
|
||||
aniplayer_queue(&boss->ani, "dance", 0);
|
||||
real tfactor = difficulty_value(1.05, 1.5, 1.95, 2.4);
|
||||
|
||||
INVOKE_SUBTASK(limiters, ENT_BOX(boss));
|
||||
INVOKE_SUBTASK(spawners, ENT_BOX(boss), .tfactor = tfactor);
|
||||
|
||||
if(global.diff > D_Easy) {
|
||||
INVOKE_SUBTASK(balls, ENT_BOX(boss));
|
||||
}
|
||||
|
||||
for(int time = 0;; ++time, YIELD) {
|
||||
real t = time * tfactor;
|
||||
real moverad = fmin(160, time/2.7);
|
||||
boss->pos = VIEWPORT_W/2 + VIEWPORT_H*I/2 + sin(t/50.0) * moverad * cdir(M_PI/2 * t/100.0);
|
||||
}
|
||||
}
|
108
src/stages/stage3/spells/logic_bomb.c
Normal file
108
src/stages/stage3/spells/logic_bomb.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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 "spells.h"
|
||||
#include "../scuttle.h"
|
||||
|
||||
#include "common_tasks.h"
|
||||
#include "global.h"
|
||||
|
||||
#define SHOT_OFS1 CMPLX(20, 8)
|
||||
#define SHOT_OFS2 CMPLX(-14, -42)
|
||||
|
||||
TASK(limiters, { BoxedBoss boss; }) {
|
||||
Boss *boss = TASK_BIND(ARGS.boss);
|
||||
|
||||
real angle = 3*M_PI/2;
|
||||
real final_angle = M_PI/16;
|
||||
|
||||
for(int time = 0;; time += WAIT(3)) {
|
||||
play_sfx_loop("shot1_loop");
|
||||
|
||||
for(int i = -1; i < 2; i += 2) {
|
||||
real c = psin(time/10.0);
|
||||
cmplx aim = cnormalize(global.plr.pos - boss->pos);
|
||||
cmplx v = 8 * aim * cdir(i * angle);
|
||||
PROJECTILE(
|
||||
.proto = pp_crystal,
|
||||
.pos = boss->pos + SHOT_OFS2,
|
||||
.color = RGBA_MUL_ALPHA(0.3 + c * 0.7, 0.6 - c * 0.3, 0.3, 0.7),
|
||||
.move = move_linear(v),
|
||||
);
|
||||
}
|
||||
|
||||
angle = lerp(angle, final_angle, 0.02);
|
||||
}
|
||||
}
|
||||
|
||||
TASK(recursive_ball, { cmplx origin; cmplx dir; real angle; ProjFlags flags; }) {
|
||||
auto p = TASK_BIND(PROJECTILE(
|
||||
.proto = pp_ball,
|
||||
.pos = ARGS.origin,
|
||||
.color = RGB(1.0, 1.0, 0.3),
|
||||
.move = move_asymptotic_halflife(3 * ARGS.dir, 0, 13),
|
||||
.flags = ARGS.flags,
|
||||
));
|
||||
|
||||
WAIT(difficulty_value(60, 60, 60, 50));
|
||||
|
||||
cmplx r = cdir(ARGS.angle);
|
||||
|
||||
play_sfx("redirect");
|
||||
|
||||
real a = ARGS.angle * 0.75;
|
||||
|
||||
if(a > M_PI/32) {
|
||||
INVOKE_TASK(recursive_ball, p->pos, ARGS.dir * r, a);
|
||||
INVOKE_TASK(recursive_ball, p->pos, ARGS.dir / r, a, PFLAG_NOSPAWNFLARE);
|
||||
} else {
|
||||
spawn_projectile_highlight_effect(p);
|
||||
}
|
||||
|
||||
if(global.diff > D_Easy) {
|
||||
p->color.r = 0;
|
||||
projectile_set_prototype(p, pp_thickrice);
|
||||
WAIT(difficulty_value(0, 120, 120, 100));
|
||||
spawn_projectile_highlight_effect(p);
|
||||
}
|
||||
|
||||
kill_projectile(p);
|
||||
}
|
||||
|
||||
TASK(recursive_balls, { BoxedBoss boss; }) {
|
||||
auto boss = TASK_BIND(ARGS.boss);
|
||||
|
||||
int delay = difficulty_value(120, 120, 60, 50);
|
||||
|
||||
for(;;WAIT(delay)) {
|
||||
cmplx o = boss->pos + boss_get_sprite_offset(boss) + SHOT_OFS2;
|
||||
cmplx d = cnormalize(global.plr.pos - o + 32 * rng_dir());
|
||||
play_sfx("shot_special1");
|
||||
INVOKE_TASK(recursive_ball, o, d, M_PI/2);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_EXTERN_TASK(stage3_spell_logic_bomb) {
|
||||
Boss *boss = INIT_BOSS_ATTACK(&ARGS);
|
||||
boss->move = move_from_towards(boss->pos, VIEWPORT_W/2 + VIEWPORT_H*I/2, 0.08);
|
||||
BEGIN_BOSS_ATTACK(&ARGS);
|
||||
boss->move.attraction = 0;
|
||||
|
||||
aniplayer_queue(&boss->ani, "dance", 0);
|
||||
|
||||
INVOKE_SUBTASK(limiters, ENT_BOX(boss));
|
||||
INVOKE_SUBTASK_DELAYED(20, recursive_balls, ENT_BOX(boss));
|
||||
|
||||
for(int time = 0;; ++time, YIELD) {
|
||||
real t = time * 1.5;
|
||||
real moverad = fmin(160, time/2.7);
|
||||
boss->pos = VIEWPORT_W/2 + VIEWPORT_H*I/2 + sin(t/50.0) * moverad * cdir(M_PI/2 * t/100.0);
|
||||
}
|
||||
}
|
|
@ -15,4 +15,4 @@ DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_firefly_storm, BossAttack);
|
|||
DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_light_singularity, BossAttack);
|
||||
DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_moonlight_rocket, BossAttack);
|
||||
DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_night_ignite, BossAttack);
|
||||
DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_deadly_dance, BossAttack);
|
||||
DECLARE_EXTERN_TASK_WITH_INTERFACE(stage3_spell_logic_bomb, BossAttack);
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
struct stage3_spells_s stage3_spells = {
|
||||
.mid = {
|
||||
.deadly_dance = {
|
||||
{ 0, 1, 2, 3}, AT_SurvivalSpell, "Venom Sign “Deadly Dance”", 14, 40000,
|
||||
TASK_INDIRECT_INIT(BossAttack, stage3_spell_deadly_dance),
|
||||
{ 0, 1, 2, 3}, AT_SurvivalSpell, "Disruption “Logic Bomb”", 14, 40000,
|
||||
TASK_INDIRECT_INIT(BossAttack, stage3_spell_logic_bomb),
|
||||
stage3_draw_scuttle_spellbg, VIEWPORT_W/2.0+100*I, 3,
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue