(attempt to) prevent draw code from altering state
This commit is contained in:
parent
d34ccb9beb
commit
76ee80b6da
23 changed files with 396 additions and 172 deletions
15
src/boss.c
15
src/boss.c
|
@ -195,10 +195,7 @@ static Projectile* spawn_boss_glow(Boss *boss, Color clr, int timeout) {
|
|||
);
|
||||
}
|
||||
|
||||
void draw_boss_background(Boss *boss) {
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(boss->pos), cimag(boss->pos), 0);
|
||||
|
||||
static void spawn_particle_effects(Boss *boss) {
|
||||
Color glowcolor = boss->glowcolor;
|
||||
Color shadowcolor = boss->shadowcolor;
|
||||
|
||||
|
@ -222,6 +219,11 @@ void draw_boss_background(Boss *boss) {
|
|||
float a = (1.0 - glowstr) + glowstr * pow(psin(global.frames/15.0), 1.0);
|
||||
spawn_boss_glow(boss, multiply_colors(glowcolor, rgb(a, a, a)), 24);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_boss_background(Boss *boss) {
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(boss->pos), cimag(boss->pos), 0);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glRotatef(global.frames*4.0, 0, 0, -1);
|
||||
|
@ -553,8 +555,11 @@ void process_boss(Boss **pboss) {
|
|||
boss->global_rule(boss, global.frames - boss->birthtime);
|
||||
}
|
||||
|
||||
if(!boss->current)
|
||||
spawn_particle_effects(boss);
|
||||
|
||||
if(!boss->current || global.dialog) {
|
||||
return;
|
||||
}
|
||||
|
||||
int time = global.frames - boss->current->starttime;
|
||||
bool extra = boss->current->type == AT_ExtraSpell;
|
||||
|
|
81
src/enemy.c
81
src/enemy.c
|
@ -14,8 +14,24 @@
|
|||
#include "list.h"
|
||||
#include "aniplayer.h"
|
||||
|
||||
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
|
||||
#ifdef create_enemy_p
|
||||
#undef create_enemy_p
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
Enemy* _enemy_attach_dbginfo(Enemy *e, DebugInfo *dbg) {
|
||||
memcpy(&e->debug, dbg, sizeof(DebugInfo));
|
||||
set_debug_info(dbg);
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
|
||||
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyVisualRule visual_rule, EnemyLogicRule logic_rule,
|
||||
complex a1, complex a2, complex a3, complex a4) {
|
||||
if(IN_DRAW_CODE) {
|
||||
log_fatal("Tried to spawn an enemy while in drawing code");
|
||||
}
|
||||
|
||||
Enemy *e = (Enemy *)create_element((void **)enemies, sizeof(Enemy));
|
||||
e->moving = false;
|
||||
e->dir = 0;
|
||||
|
@ -28,7 +44,7 @@ Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_r
|
|||
e->alpha = 1.0;
|
||||
|
||||
e->logic_rule = logic_rule;
|
||||
e->draw_rule = draw_rule;
|
||||
e->visual_rule = visual_rule;
|
||||
|
||||
e->args[0] = a1;
|
||||
e->args[1] = a2;
|
||||
|
@ -53,9 +69,9 @@ void _delete_enemy(void **enemies, void* enemy) {
|
|||
);
|
||||
}
|
||||
|
||||
PARTICLE("blast", e->pos, 0, timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", e->pos, 0, timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", e->pos, 0, timeout, { 15 }, .draw_rule = GrowFade);
|
||||
PARTICLE("blast", e->pos, 0, blast_timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", e->pos, 0, blast_timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", e->pos, 0, blast_timeout, { 15 }, .draw_rule = GrowFade);
|
||||
}
|
||||
|
||||
e->logic_rule(enemy, EVENT_DEATH);
|
||||
|
@ -72,12 +88,27 @@ void delete_enemies(Enemy **enemies) {
|
|||
delete_all_elements((void **)enemies, _delete_enemy);
|
||||
}
|
||||
|
||||
static void draw_enemy(Enemy *e) {
|
||||
#ifdef ENEMY_DEBUG
|
||||
static Enemy prev_state;
|
||||
memcpy(&prev_state, e, sizeof(Enemy));
|
||||
e->visual_rule(e, global.frames - e->birthtime, true);
|
||||
|
||||
if(memcmp(&prev_state, e, sizeof(Enemy))) {
|
||||
set_debug_info(&e->debug);
|
||||
log_fatal("Enemy modified its own state in draw rule");
|
||||
}
|
||||
#else
|
||||
e->visual_rule(e, global.frames - e->birthtime, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void draw_enemies(Enemy *enemies) {
|
||||
Enemy *e;
|
||||
bool reset = false;
|
||||
|
||||
for(e = enemies; e; e = e->next) {
|
||||
if(e->draw_rule) {
|
||||
if(e->visual_rule) {
|
||||
if(e->alpha < 1) {
|
||||
e->alpha += 1 / 60.0;
|
||||
if(e->alpha > 1)
|
||||
|
@ -87,7 +118,8 @@ void draw_enemies(Enemy *enemies) {
|
|||
reset = true;
|
||||
}
|
||||
|
||||
e->draw_rule(e, global.frames - e->birthtime);
|
||||
draw_enemy(e);
|
||||
|
||||
if(reset)
|
||||
glColor4f(1,1,1,1);
|
||||
}
|
||||
|
@ -140,15 +172,19 @@ void EnemyFlareShrink(Projectile *p, int t) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
void BigFairy(Enemy *e, int t) {
|
||||
if(!(t % 5)) {
|
||||
complex offset = (frand()-0.5)*30 + (frand()-0.5)*20.0*I;
|
||||
void BigFairy(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
if(!(t % 5)) {
|
||||
complex offset = (frand()-0.5)*30 + (frand()-0.5)*20.0*I;
|
||||
|
||||
PARTICLE("lasercurve", offset, rgb(0,0.2,0.3), enemy_flare,
|
||||
.draw_rule = EnemyFlareShrink,
|
||||
.args = { 50, (-50.0*I-offset)/50.0, add_ref(e) },
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
PARTICLE("lasercurve", offset, rgb(0,0.2,0.3), enemy_flare,
|
||||
.draw_rule = EnemyFlareShrink,
|
||||
.args = { 50, (-50.0*I-offset)/50.0, add_ref(e) },
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
|
@ -173,7 +209,10 @@ void BigFairy(Enemy *e, int t) {
|
|||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
void Fairy(Enemy *e, int t) {
|
||||
void Fairy(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
float s = sin((float)(global.frames-e->birthtime)/10.f)/6 + 0.8;
|
||||
glPushMatrix();
|
||||
|
@ -200,7 +239,11 @@ void Fairy(Enemy *e, int t) {
|
|||
}
|
||||
}
|
||||
|
||||
void Swirl(Enemy *e, int t) {
|
||||
void Swirl(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(e->pos), cimag(e->pos),0);
|
||||
glRotatef(t*15,0,0,1);
|
||||
|
@ -225,6 +268,10 @@ void process_enemies(Enemy **enemies) {
|
|||
enemy = enemy->next;
|
||||
delete_enemy(enemies, del);
|
||||
} else {
|
||||
if(enemy->visual_rule) {
|
||||
enemy->visual_rule(enemy, global.frames - enemy->birthtime, false);
|
||||
}
|
||||
|
||||
enemy = enemy->next;
|
||||
}
|
||||
}
|
||||
|
|
25
src/enemy.h
25
src/enemy.h
|
@ -11,9 +11,13 @@
|
|||
#include "util.h"
|
||||
#include "projectile.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ENEMY_DEBUG
|
||||
#endif
|
||||
|
||||
typedef struct Enemy Enemy;
|
||||
typedef int (*EnemyLogicRule)(struct Enemy*, int t);
|
||||
typedef void (*EnemyDrawRule)(struct Enemy*, int t);
|
||||
typedef void (*EnemyVisualRule)(struct Enemy*, int t, bool render);
|
||||
|
||||
enum {
|
||||
ENEMY_IMMUNE = -9000,
|
||||
|
@ -33,12 +37,16 @@ struct Enemy {
|
|||
bool moving;
|
||||
|
||||
EnemyLogicRule logic_rule;
|
||||
EnemyDrawRule draw_rule;
|
||||
EnemyVisualRule visual_rule;
|
||||
|
||||
int hp;
|
||||
|
||||
complex args[RULE_ARGC];
|
||||
float alpha;
|
||||
|
||||
#ifdef ENEMY_DEBUG
|
||||
DebugInfo debug;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define create_enemy4c(p,h,d,l,a1,a2,a3,a4) create_enemy_p(&global.enemies,p,h,d,l,a1,a2,a3,a4)
|
||||
|
@ -46,8 +54,13 @@ struct Enemy {
|
|||
#define create_enemy2c(p,h,d,l,a1,a2) create_enemy_p(&global.enemies,p,h,d,l,a1,a2,0,0)
|
||||
#define create_enemy1c(p,h,d,l,a1) create_enemy_p(&global.enemies,p,h,d,l,a1,0,0,0)
|
||||
|
||||
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rule, EnemyLogicRule logic_rule,
|
||||
Enemy *create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyVisualRule draw_rule, EnemyLogicRule logic_rule,
|
||||
complex a1, complex a2, complex a3, complex a4);
|
||||
#ifdef ENEMY_DEBUG
|
||||
Enemy* _enemy_attach_dbginfo(Enemy *p, DebugInfo *dbg);
|
||||
#define create_enemy_p(...) _enemy_attach_dbginfo(create_enemy_p(__VA_ARGS__), _DEBUG_INFO_PTR_)
|
||||
#endif
|
||||
|
||||
void delete_enemy(Enemy **enemies, Enemy* enemy);
|
||||
void draw_enemies(Enemy *enemies);
|
||||
void delete_enemies(Enemy **enemies);
|
||||
|
@ -56,9 +69,9 @@ void process_enemies(Enemy **enemies);
|
|||
|
||||
void killall(Enemy *enemies);
|
||||
|
||||
void Fairy(Enemy*, int t);
|
||||
void Swirl(Enemy*, int t);
|
||||
void BigFairy(Enemy*, int t);
|
||||
void Fairy(Enemy*, int t, bool render);
|
||||
void Swirl(Enemy*, int t, bool render);
|
||||
void BigFairy(Enemy*, int t, bool render);
|
||||
|
||||
int enemy_flare(Projectile *p, int t);
|
||||
void EnemyFlareShrink(Projectile *p, int t);
|
||||
|
|
25
src/log.c
25
src/log.c
|
@ -44,7 +44,7 @@ static const char* level_prefix(LogLevel lvl) {
|
|||
return level_prefix_map[idx];
|
||||
}
|
||||
|
||||
static char* format_log_string(LogLevel lvl, const char *funcname, const char *fmt, va_list args) {
|
||||
static char* format_log_string(LogLevel lvl, const char *funcname, const char *fmt, va_list args, bool is_backtrace) {
|
||||
const char *pref = level_prefix(lvl);
|
||||
char *msg = vstrfmt(fmt, args);
|
||||
char *final = strfmt("%-9d %s: %s(): %s%s", SDL_GetTicks(), pref, funcname, msg, LOG_EOL);
|
||||
|
@ -52,6 +52,27 @@ static char* format_log_string(LogLevel lvl, const char *funcname, const char *f
|
|||
|
||||
// TODO: maybe convert all \n in the message to LOG_EOL
|
||||
|
||||
#ifdef DEBUG
|
||||
if((backtrace_log_levels & lvl) && !is_backtrace) {
|
||||
DebugInfo *debug_info = get_debug_info();
|
||||
DebugInfo *debug_meta = get_debug_meta();
|
||||
|
||||
msg = final;
|
||||
final = strfmt(
|
||||
"%s%s%s"
|
||||
"Debug info: %s:%i:%s%s"
|
||||
"Debug info set at: %s:%i:%s%s"
|
||||
"Note: debug info may not be relevant to this issue%s",
|
||||
msg, LOG_EOL, LOG_EOL,
|
||||
debug_info->file, debug_info->line, debug_info->func, LOG_EOL,
|
||||
debug_meta->file, debug_meta->line, debug_meta->func, LOG_EOL,
|
||||
LOG_EOL
|
||||
);
|
||||
|
||||
free(msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
|
@ -81,7 +102,7 @@ static void log_internal(LogLevel lvl, bool is_backtrace, const char *funcname,
|
|||
for(Logger *l = loggers; l; l = l->next) {
|
||||
if(l->levels & lvl) {
|
||||
if(!str) {
|
||||
str = format_log_string(lvl, funcname, fmt, args);
|
||||
str = format_log_string(lvl, funcname, fmt, args, is_backtrace);
|
||||
slen = strlen(str);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,11 @@ void marisa_common_shot(Player *plr) {
|
|||
}
|
||||
}
|
||||
|
||||
void marisa_common_slave_draw(Enemy *e, int t) {
|
||||
void marisa_common_slave_visual(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(e->pos), cimag(e->pos), -1);
|
||||
// glRotatef(global.frames * 3, 0, 0, 1);
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
extern PlayerCharacter character_marisa;
|
||||
|
||||
void marisa_common_shot(Player *plr);
|
||||
void marisa_common_slave_draw(Enemy *e, int t);
|
||||
void marisa_common_slave_visual(Enemy *e, int t, bool render);
|
||||
|
|
|
@ -109,7 +109,12 @@ static void draw_magic_star(complex pos, double a, Color c1, Color c2) {
|
|||
glUseProgram(0);
|
||||
}
|
||||
|
||||
static void marisa_laser_slave_draw(Enemy *e, int t) {
|
||||
static void marisa_laser_slave_visual(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
marisa_common_slave_visual(e, t, render);
|
||||
return;
|
||||
}
|
||||
|
||||
float laser_alpha = global.plr.slaves->args[0];
|
||||
float star_alpha = global.plr.slaves->args[1];
|
||||
|
||||
|
@ -118,7 +123,7 @@ static void marisa_laser_slave_draw(Enemy *e, int t) {
|
|||
rgb(0.0, 0.1, 1.1)
|
||||
);
|
||||
|
||||
marisa_common_slave_draw(e, t);
|
||||
marisa_common_slave_visual(e, t, render);
|
||||
|
||||
if(laser_alpha <= 0) {
|
||||
return;
|
||||
|
@ -132,11 +137,11 @@ static void marisa_laser_slave_draw(Enemy *e, int t) {
|
|||
glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
static void marisa_laser_fader_draw(Enemy *e, int t) {
|
||||
static void marisa_laser_fader_visual(Enemy *e, int t, bool render) {
|
||||
}
|
||||
|
||||
static float get_laser_alpha(Enemy *e, float a) {
|
||||
if(e->draw_rule == marisa_laser_fader_draw) {
|
||||
if(e->visual_rule == marisa_laser_fader_visual) {
|
||||
return e->args[1];
|
||||
}
|
||||
|
||||
|
@ -144,9 +149,13 @@ static float get_laser_alpha(Enemy *e, float a) {
|
|||
}
|
||||
|
||||
#define FOR_EACH_SLAVE(e) for(Enemy *e = global.plr.slaves; e; e = e->next) if(e != renderer)
|
||||
#define FOR_EACH_REAL_SLAVE(e) FOR_EACH_SLAVE(e) if(e->draw_rule == marisa_laser_slave_draw)
|
||||
#define FOR_EACH_REAL_SLAVE(e) FOR_EACH_SLAVE(e) if(e->visual_rule == marisa_laser_slave_visual)
|
||||
|
||||
static void marisa_laser_renderer_visual(Enemy *renderer, int t, bool render) {
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void marisa_laser_renderer_draw(Enemy *renderer, int t) {
|
||||
double a = creal(renderer->args[0]);
|
||||
Shader *shader = get_shader("marisa_laser");
|
||||
int u_clr0 = uniloc(shader, "color0");
|
||||
|
@ -218,7 +227,7 @@ static int marisa_laser_fader(Enemy *e, int t) {
|
|||
}
|
||||
|
||||
static Enemy* spawn_laser_fader(Enemy *e, double alpha) {
|
||||
return create_enemy_p(&global.plr.slaves, e->pos, ENEMY_IMMUNE, marisa_laser_fader_draw, marisa_laser_fader,
|
||||
return create_enemy_p(&global.plr.slaves, e->pos, ENEMY_IMMUNE, marisa_laser_fader_visual, marisa_laser_fader,
|
||||
e->args[0], alpha, e->args[2], e->args[3]);
|
||||
}
|
||||
|
||||
|
@ -290,7 +299,11 @@ static void masterspark_ring_draw(complex base, int t, float fade) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
static void masterspark_draw(Enemy *e, int t) {
|
||||
static void masterspark_visual(Enemy *e, int t, bool render) {
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
t = player_get_bomb_progress(&global.plr, NULL) * (e->args[0] / BOMB_RECOVERY);
|
||||
|
||||
glPushMatrix();
|
||||
|
@ -340,7 +353,7 @@ static int masterspark(Enemy *e, int t) {
|
|||
|
||||
static void marisa_laser_bomb(Player *plr) {
|
||||
play_sound("bomb_marisa_a");
|
||||
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_BOMB, masterspark_draw, masterspark, 280,0,0,0);
|
||||
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_BOMB, masterspark_visual, masterspark, 280,0,0,0);
|
||||
}
|
||||
|
||||
static void marisa_laser_respawn_slaves(Player *plr, short npow) {
|
||||
|
@ -356,21 +369,21 @@ static void marisa_laser_respawn_slaves(Player *plr, short npow) {
|
|||
}
|
||||
|
||||
if(npow / 100 == 1) {
|
||||
create_enemy_p(&plr->slaves, -40.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, -40.0*I, dmg, 0, 0);
|
||||
create_enemy_p(&plr->slaves, -40.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, -40.0*I, dmg, 0, 0);
|
||||
}
|
||||
|
||||
if(npow >= 200) {
|
||||
create_enemy_p(&plr->slaves, 25-5.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, 8-40.0*I, dmg, -M_PI/30, 0);
|
||||
create_enemy_p(&plr->slaves, -25-5.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, -8-40.0*I, dmg, M_PI/30, 0);
|
||||
create_enemy_p(&plr->slaves, 25-5.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, 8-40.0*I, dmg, -M_PI/30, 0);
|
||||
create_enemy_p(&plr->slaves, -25-5.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, -8-40.0*I, dmg, M_PI/30, 0);
|
||||
}
|
||||
|
||||
if(npow / 100 == 3) {
|
||||
create_enemy_p(&plr->slaves, -30.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, -50.0*I, dmg, 0, 0);
|
||||
create_enemy_p(&plr->slaves, -30.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, -50.0*I, dmg, 0, 0);
|
||||
}
|
||||
|
||||
if(npow >= 400) {
|
||||
create_enemy_p(&plr->slaves, 17-30.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, 4-45.0*I, dmg, M_PI/60, 0);
|
||||
create_enemy_p(&plr->slaves, -17-30.0*I, ENEMY_IMMUNE, marisa_laser_slave_draw, marisa_laser_slave, -4-45.0*I, dmg, -M_PI/60, 0);
|
||||
create_enemy_p(&plr->slaves, 17-30.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, 4-45.0*I, dmg, M_PI/60, 0);
|
||||
create_enemy_p(&plr->slaves, -17-30.0*I, ENEMY_IMMUNE, marisa_laser_slave_visual, marisa_laser_slave, -4-45.0*I, dmg, -M_PI/60, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,7 +396,7 @@ static void marisa_laser_power(Player *plr, short npow) {
|
|||
}
|
||||
|
||||
static void marisa_laser_init(Player *plr) {
|
||||
create_enemy_p(&plr->slaves, 0, ENEMY_IMMUNE, marisa_laser_renderer_draw, marisa_laser_renderer, 0, 0, 0, 0);
|
||||
create_enemy_p(&plr->slaves, 0, ENEMY_IMMUNE, marisa_laser_renderer_visual, marisa_laser_renderer, 0, 0, 0, 0);
|
||||
marisa_laser_respawn_slaves(plr, plr->power);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,21 +157,21 @@ static void marisa_star_respawn_slaves(Player *plr, short npow) {
|
|||
}
|
||||
|
||||
if(npow / 100 == 1) {
|
||||
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, +30.0*I, -2.0*I, -0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, +30.0*I, -2.0*I, -0.1*I, dmg);
|
||||
}
|
||||
|
||||
if(npow >= 200) {
|
||||
create_enemy_p(&plr->slaves, 30.0*I+15, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, +30.0*I+10, -0.3-2.0*I, 1-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, 30.0*I-15, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, +30.0*I-10, 0.3-2.0*I, -1-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, 30.0*I+15, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, +30.0*I+10, -0.3-2.0*I, 1-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, 30.0*I-15, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, +30.0*I-10, 0.3-2.0*I, -1-0.1*I, dmg);
|
||||
}
|
||||
|
||||
if(npow / 100 == 3) {
|
||||
create_enemy_p(&plr->slaves, -30.0*I, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, +30.0*I, -2.0*I, -0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, -30.0*I, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, +30.0*I, -2.0*I, -0.1*I, dmg);
|
||||
}
|
||||
|
||||
if(npow >= 400) {
|
||||
create_enemy_p(&plr->slaves, 30, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, 25+30.0*I, -0.6-2.0*I, 2-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, -30, ENEMY_IMMUNE, marisa_common_slave_draw, marisa_star_slave, -25+30.0*I, 0.6-2.0*I, -2-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, 30, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, 25+30.0*I, -0.6-2.0*I, 2-0.1*I, dmg);
|
||||
create_enemy_p(&plr->slaves, -30, ENEMY_IMMUNE, marisa_common_slave_visual, marisa_star_slave, -25+30.0*I, 0.6-2.0*I, -2-0.1*I, dmg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,17 +36,7 @@ int youmu_common_particle_spin(Projectile *p, int t) {
|
|||
}
|
||||
|
||||
void youmu_common_particle_slice_draw(Projectile *p, int t) {
|
||||
if(t < creal(p->args[0])/20.0)
|
||||
p->args[1] += 1;
|
||||
|
||||
if(t > creal(p->args[0])-10) {
|
||||
p->args[1] += 3;
|
||||
p->args[2] += 1;
|
||||
}
|
||||
|
||||
float f = p->args[1]/p->args[0]*20.0;
|
||||
p->color = rgba(1, 1, 1, 1 - p->args[2]/p->args[0]*20.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(p->pos), cimag(p->pos),0);
|
||||
glRotatef(p->angle/M_PI*180,0,0,1);
|
||||
|
@ -56,6 +46,25 @@ void youmu_common_particle_slice_draw(Projectile *p, int t) {
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
int youmu_common_particle_slice_logic(Projectile *p, int t) {
|
||||
if(t < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
p->color = rgba(1, 1, 1, 1 - p->args[2]/p->args[0]*20.0);
|
||||
|
||||
if(t < creal(p->args[0])/20.0) {
|
||||
p->args[1] += 1;
|
||||
}
|
||||
|
||||
if(t > creal(p->args[0])-10) {
|
||||
p->args[1] += 3;
|
||||
p->args[2] += 1;
|
||||
}
|
||||
|
||||
return timeout(p, t);
|
||||
}
|
||||
|
||||
void youmu_common_shot(Player *plr) {
|
||||
if(!(global.frames % 4)) {
|
||||
play_sound("generic_shot");
|
||||
|
|
|
@ -16,4 +16,5 @@ extern PlayerCharacter character_youmu;
|
|||
|
||||
int youmu_common_particle_spin(Projectile *p, int t);
|
||||
void youmu_common_particle_slice_draw(Projectile *p, int t);
|
||||
int youmu_common_particle_slice_logic(Projectile *p, int t);
|
||||
void youmu_common_shot(Player *plr);
|
||||
|
|
|
@ -145,7 +145,7 @@ static int youmu_split_logic(void *v, int t, double speed) {
|
|||
.texture = "youmu_slice",
|
||||
.pos = VIEWPORT_W/2.0 + VIEWPORT_H/2.0*I - 200-200.0*I + 400*afrand(0)+400.0*I*afrand(1),
|
||||
.draw_rule = youmu_common_particle_slice_draw,
|
||||
.rule = timeout,
|
||||
.rule = youmu_common_particle_slice_logic,
|
||||
.args = { (100 - _i) / speed },
|
||||
.angle = M_PI * 2 * afrand(2),
|
||||
.type = PlrProj,
|
||||
|
|
|
@ -93,7 +93,7 @@ static int youmu_homing(Projectile *p, int t) { // a[0]: velocity, a[1]: aim (r:
|
|||
|
||||
static int youmu_trap(Projectile *p, int t) {
|
||||
if(t == EVENT_DEATH) {
|
||||
PARTICLE("blast", p->pos, 0, timeout, { 15 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", p->pos, 0, blast_timeout, { 15 }, .draw_rule = Blast);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -104,8 +104,8 @@ static int youmu_trap(Projectile *p, int t) {
|
|||
}
|
||||
|
||||
if(!(global.plr.inputflags & INFLAG_FOCUS)) {
|
||||
PARTICLE("blast", p->pos, 0, timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", p->pos, 0, timeout, { 23 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", p->pos, 0, blast_timeout, { 20 }, .draw_rule = Blast);
|
||||
PARTICLE("blast", p->pos, 0, blast_timeout, { 23 }, .draw_rule = Blast);
|
||||
|
||||
int cnt = creal(p->args[2]);
|
||||
int dmg = cimag(p->args[2]);
|
||||
|
@ -134,9 +134,11 @@ static int youmu_trap(Projectile *p, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void YoumuSlash(Enemy *e, int t) {
|
||||
t = player_get_bomb_progress(&global.plr, NULL);
|
||||
fade_out(10.0/t+sin(t/10.0)*0.1);
|
||||
static void YoumuSlash(Enemy *e, int t, bool render) {
|
||||
if(render) {
|
||||
t = player_get_bomb_progress(&global.plr, NULL);
|
||||
fade_out(10.0/t+sin(t/10.0)*0.1);
|
||||
}
|
||||
}
|
||||
|
||||
static int youmu_slash_logic(void *v, int t, double speed) {
|
||||
|
@ -156,7 +158,7 @@ static int youmu_slash_logic(void *v, int t, double speed) {
|
|||
.texture = "youmu_slice",
|
||||
.pos = VIEWPORT_W/2.0 - 150 + 100*_i + VIEWPORT_H/2.0*I - 10-10.0*I + 20*afrand(0)+20.0*I*afrand(1),
|
||||
.draw_rule = youmu_common_particle_slice_draw,
|
||||
.rule = timeout,
|
||||
.rule = youmu_common_particle_slice_logic,
|
||||
.args = { 200 / speed },
|
||||
.angle = 10 * anfrand(2),
|
||||
.type = PlrProj,
|
||||
|
|
|
@ -103,6 +103,10 @@ int projectile_prio_func(void *vproj) {
|
|||
}
|
||||
|
||||
static Projectile* _create_projectile(ProjArgs *args) {
|
||||
if(IN_DRAW_CODE) {
|
||||
log_fatal("Tried to spawn a projectile while in drawing code");
|
||||
}
|
||||
|
||||
Projectile *p = create_element_at_priority(
|
||||
(void**)args->dest, sizeof(Projectile),
|
||||
projectile_prio_rawfunc(args->texture_ptr, args->size),
|
||||
|
@ -144,8 +148,9 @@ Projectile* create_particle(ProjArgs *args) {
|
|||
}
|
||||
|
||||
#ifdef PROJ_DEBUG
|
||||
Projectile* _proj_attach_dbginfo(Projectile *p, ProjDebugInfo *dbg) {
|
||||
memcpy(&p->debug, dbg, sizeof(ProjDebugInfo));
|
||||
Projectile* _proj_attach_dbginfo(Projectile *p, DebugInfo *dbg) {
|
||||
memcpy(&p->debug, dbg, sizeof(DebugInfo));
|
||||
set_debug_info(dbg);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
@ -244,17 +249,28 @@ void proj_clrtransform_particle(Projectile *p, int t, Color c, ColorTransform *o
|
|||
}
|
||||
|
||||
static inline void draw_projectile(Projectile *proj) {
|
||||
#ifdef PROJ_DEBUG
|
||||
static Projectile prev_state;
|
||||
memcpy(&prev_state, proj, sizeof(Projectile));
|
||||
|
||||
proj->draw_rule(proj, global.frames - proj->birthtime);
|
||||
|
||||
#ifdef PROJ_DEBUG
|
||||
int cur_shader;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &cur_shader); // NOTE: this can be really slow!
|
||||
if(memcmp(&prev_state, proj, sizeof(Projectile))) {
|
||||
set_debug_info(&proj->debug);
|
||||
log_fatal("Projectile modified its state in draw rule");
|
||||
}
|
||||
|
||||
if(cur_shader != recolor_get_shader()->prog) {
|
||||
log_fatal("Bad shader after drawing projectile. Offending spawn: %s:%u:%s",
|
||||
proj->debug.file, proj->debug.line, proj->debug.func
|
||||
);
|
||||
}
|
||||
/*
|
||||
int cur_shader;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &cur_shader); // NOTE: this can be really slow!
|
||||
|
||||
if(cur_shader != recolor_get_shader()->prog) {
|
||||
set_debug_info(&proj->debug);
|
||||
log_fatal("Bad shader after drawing projectile");
|
||||
}
|
||||
*/
|
||||
#else
|
||||
proj->draw_rule(proj, global.frames - proj->birthtime);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -450,12 +466,16 @@ void ProjDraw(Projectile *proj, int t) {
|
|||
void ProjNoDraw(Projectile *proj, int t) {
|
||||
}
|
||||
|
||||
void Blast(Projectile *p, int t) {
|
||||
int blast_timeout(Projectile *p, int t) {
|
||||
if(t == 1) {
|
||||
p->args[1] = frand()*360 + frand()*I;
|
||||
p->args[2] = frand() + frand()*I;
|
||||
}
|
||||
|
||||
return timeout(p, t);
|
||||
}
|
||||
|
||||
void Blast(Projectile *p, int t) {
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(p->pos), cimag(p->pos), 0);
|
||||
glRotatef(creal(p->args[1]), cimag(p->args[1]), creal(p->args[2]), cimag(p->args[2]));
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "recolor.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
// #define PROJ_DEBUG
|
||||
#define PROJ_DEBUG
|
||||
#endif
|
||||
|
||||
enum {
|
||||
|
@ -51,14 +51,6 @@ typedef enum ProjFlags {
|
|||
PFLAG_NOGRAZE = (1 << 3),
|
||||
} ProjFlags;
|
||||
|
||||
#ifdef PROJ_DEBUG
|
||||
typedef struct ProjDebugInfo {
|
||||
const char *file;
|
||||
const char *func;
|
||||
unsigned int line;
|
||||
} ProjDebugInfo;
|
||||
#endif
|
||||
|
||||
struct Projectile {
|
||||
struct Projectile *next;
|
||||
struct Projectile *prev;
|
||||
|
@ -79,7 +71,7 @@ struct Projectile {
|
|||
bool grazed;
|
||||
|
||||
#ifdef PROJ_DEBUG
|
||||
ProjDebugInfo debug;
|
||||
DebugInfo debug;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -104,9 +96,9 @@ Projectile* create_projectile(ProjArgs *args);
|
|||
Projectile* create_particle(ProjArgs *args);
|
||||
|
||||
#ifdef PROJ_DEBUG
|
||||
Projectile* _proj_attach_dbginfo(Projectile *p, ProjDebugInfo *dbg);
|
||||
#define PROJECTILE(...) _proj_attach_dbginfo(create_projectile(&(ProjArgs) { __VA_ARGS__ }), &(ProjDebugInfo) { __FILE__, __func__, __LINE__ })
|
||||
#define PARTICLE(...) _proj_attach_dbginfo(create_particle(&(ProjArgs) { __VA_ARGS__ }), &(ProjDebugInfo) { __FILE__, __func__, __LINE__ })
|
||||
Projectile* _proj_attach_dbginfo(Projectile *p, DebugInfo *dbg);
|
||||
#define PROJECTILE(...) _proj_attach_dbginfo(create_projectile(&(ProjArgs) { __VA_ARGS__ }), _DEBUG_INFO_PTR_)
|
||||
#define PARTICLE(...) _proj_attach_dbginfo(create_particle(&(ProjArgs) { __VA_ARGS__ }), _DEBUG_INFO_PTR_)
|
||||
#else
|
||||
#define PROJECTILE(...) create_projectile(&(ProjArgs) { __VA_ARGS__ })
|
||||
#define PARTICLE(...) create_particle(&(ProjArgs) { __VA_ARGS__ })
|
||||
|
@ -134,7 +126,7 @@ void DeathShrink(Projectile *p, int t);
|
|||
void Fade(Projectile *p, int t);
|
||||
void GrowFade(Projectile *p, int t);
|
||||
void ScaleFade(Projectile *p, int t);
|
||||
void Blast(Projectile *p, int t);
|
||||
|
||||
|
||||
void Petal(Projectile *p, int t);
|
||||
void petal_explosion(int n, complex pos);
|
||||
|
@ -142,4 +134,7 @@ void petal_explosion(int n, complex pos);
|
|||
int timeout(Projectile *p, int t);
|
||||
int timeout_linear(Projectile *p, int t);
|
||||
|
||||
int blast_timeout(Projectile *p, int t);
|
||||
void Blast(Projectile *p, int t);
|
||||
|
||||
void projectiles_preload(void);
|
||||
|
|
|
@ -395,7 +395,9 @@ static void stage_logic(void) {
|
|||
) {
|
||||
page_dialog(&global.dialog);
|
||||
}
|
||||
} else if(global.boss) {
|
||||
}
|
||||
|
||||
if(global.boss) {
|
||||
process_boss(&global.boss);
|
||||
}
|
||||
|
||||
|
@ -596,7 +598,9 @@ static bool stage_frame(void *arg) {
|
|||
|
||||
tsrand_lock(&global.rand_game);
|
||||
tsrand_switch(&global.rand_visual);
|
||||
BEGIN_DRAW_CODE();
|
||||
stage_draw_scene(stage);
|
||||
END_DRAW_CODE();
|
||||
tsrand_unlock(&global.rand_game);
|
||||
tsrand_switch(&global.rand_game);
|
||||
|
||||
|
|
|
@ -552,8 +552,12 @@ int hina_monty_slave(Enemy *s, int time) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void hina_monty_slave_draw(Enemy *s, int time) {
|
||||
Swirl(s, time);
|
||||
void hina_monty_slave_visual(Enemy *s, int time, bool render) {
|
||||
Swirl(s, time, render);
|
||||
|
||||
if(!render) {
|
||||
return;
|
||||
}
|
||||
|
||||
Texture *soul = get_tex("proj/soul");
|
||||
Shader *shader = recolor_get_shader();
|
||||
|
@ -652,7 +656,7 @@ void hina_monty(Boss *h, int time) {
|
|||
|
||||
AT(140) {
|
||||
play_sound("shot_special1");
|
||||
create_enemy4c(cwidth * (0.5 + slave_pos) + VIEWPORT_H/2.0*I - 200.0*I, ENEMY_IMMUNE, hina_monty_slave_draw, hina_monty_slave, 0, 0, 0, 1);
|
||||
create_enemy4c(cwidth * (0.5 + slave_pos) + VIEWPORT_H/2.0*I - 200.0*I, ENEMY_IMMUNE, hina_monty_slave_visual, hina_monty_slave, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
AT(190) {
|
||||
|
|
|
@ -707,23 +707,22 @@ Boss* stage3_create_midboss(void) {
|
|||
return scuttle;
|
||||
}
|
||||
|
||||
static void wriggle_slave_draw(Enemy *e, int time) {
|
||||
static void wriggle_slave_visual(Enemy *e, int time, bool render) {
|
||||
if(time < 0)
|
||||
return;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(e->pos),cimag(e->pos),0);
|
||||
glRotatef(7*time,0,0,1);
|
||||
glColor4f(0.8,1,0.4,1);
|
||||
glScalef(0.7,0.7,1);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
draw_texture(0,0,"fairy_circle");
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glColor3f(1,1,1);
|
||||
glPopMatrix();
|
||||
|
||||
if(time % 5 == 0) {
|
||||
if(render) {
|
||||
glPushMatrix();
|
||||
glTranslatef(creal(e->pos),cimag(e->pos),0);
|
||||
glRotatef(7*time,0,0,1);
|
||||
glColor4f(0.8,1,0.4,1);
|
||||
glScalef(0.7,0.7,1);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
draw_texture(0,0,"fairy_circle");
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor3f(1,1,1);
|
||||
glPopMatrix();
|
||||
} else if(time % 5 == 0) {
|
||||
tsrand_fill(2);
|
||||
PARTICLE(
|
||||
.texture = "lasercurve",
|
||||
|
@ -912,7 +911,7 @@ void wriggle_moonlight_rocket(Boss *boss, int time) {
|
|||
GO_TO(boss, VIEWPORT_W/2 + VIEWPORT_H*I/2.5, 0.05)
|
||||
else if(time == 0) {
|
||||
for(j = -1; j < 2; j += 2) for(i = 0; i < cnt; ++i)
|
||||
create_enemy3c(boss->pos, ENEMY_IMMUNE, wriggle_slave_draw, wriggle_spell_slave, add_ref(boss), i*2*M_PI/cnt, j);
|
||||
create_enemy3c(boss->pos, ENEMY_IMMUNE, wriggle_slave_visual, wriggle_spell_slave, add_ref(boss), i*2*M_PI/cnt, j);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -977,7 +976,7 @@ void wriggle_night_ignite(Boss *boss, int time) {
|
|||
}
|
||||
|
||||
AT(0) for(int j = -1; j < 2; j += 2) for(int i = 0; i < 7; ++i) {
|
||||
create_enemy4c(boss->pos, ENEMY_IMMUNE, wriggle_slave_draw, wriggle_spell_slave, add_ref(boss), i*2*M_PI/7, j, 1);
|
||||
create_enemy4c(boss->pos, ENEMY_IMMUNE, wriggle_slave_visual, wriggle_spell_slave, add_ref(boss), i*2*M_PI/7, j, 1);
|
||||
}
|
||||
|
||||
FROM_TO_INT(0, 1000000, 180, 120, 10) {
|
||||
|
@ -1259,7 +1258,7 @@ static void wriggle_nonspell_common(Boss *boss, int time, int level) {
|
|||
int i, j, cnt = 3 + global.diff;
|
||||
|
||||
AT(0) for(j = -1; j < 2; j += 2) for(i = 0; i < cnt; ++i)
|
||||
create_enemy4c(boss->pos, ENEMY_IMMUNE, wriggle_slave_draw, wriggle_nonspell_slave, add_ref(boss), i*2*M_PI/cnt, j, level);
|
||||
create_enemy4c(boss->pos, ENEMY_IMMUNE, wriggle_slave_visual, wriggle_nonspell_slave, add_ref(boss), i*2*M_PI/cnt, j, level);
|
||||
|
||||
AT(EVENT_DEATH) {
|
||||
killall(global.enemies);
|
||||
|
|
|
@ -290,7 +290,11 @@ int stage4_explosive(Enemy *e, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void KurumiSlave(Enemy *e, int t) {
|
||||
void KurumiSlave(Enemy *e, int t, bool render) {
|
||||
if(render) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(t%2)) {
|
||||
complex offset = (frand()-0.5)*30;
|
||||
offset += (frand()-0.5)*20.0*I;
|
||||
|
@ -654,7 +658,11 @@ int aniwall_slave(Enemy *e, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void KurumiAniWallSlave(Enemy *e, int t) {
|
||||
void KurumiAniWallSlave(Enemy *e, int t, bool render) {
|
||||
if(render) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(e->args[1]) {
|
||||
PARTICLE("lasercurve", e->pos, rgb(1,1,1), timeout, { 30 },
|
||||
.draw_rule = Fade,
|
||||
|
@ -1060,26 +1068,41 @@ void kurumi_extra_create_drainer(Enemy *e) {
|
|||
);
|
||||
}
|
||||
|
||||
void kurumi_swirl_draw(Enemy *e, int time) {
|
||||
void kurumi_extra_swirl_visual(Enemy *e, int time, bool render) {
|
||||
if(!render) {
|
||||
Swirl(e, time, render);
|
||||
return;
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
Swirl(e, time);
|
||||
Swirl(e, time, render);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void kurumi_extra_fairy_draw(Enemy *e, int time) {
|
||||
void kurumi_extra_fairy_visual(Enemy *e, int time, bool render) {
|
||||
if(!render) {
|
||||
Fairy(e, time, render);
|
||||
return;
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glUseProgram(get_shader("negative")->prog);
|
||||
Fairy(e, time);
|
||||
Fairy(e, time, render);
|
||||
glUseProgram(0);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void kurumi_bigfairy_draw(Enemy *e, int time) {
|
||||
void kurumi_extra_bigfairy_visual(Enemy *e, int time, bool render) {
|
||||
if(!render) {
|
||||
BigFairy(e, time, render);
|
||||
return;
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glUseProgram(get_shader("negative")->prog);
|
||||
BigFairy(e, time);
|
||||
BigFairy(e, time, render);
|
||||
glUseProgram(0);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
@ -1176,8 +1199,8 @@ void kurumi_extra(Boss *b, int time) {
|
|||
for(int i = 0; i < cnt; ++i) {
|
||||
double a = M_PI * 2 * i / (double)cnt;
|
||||
int hp = 500;
|
||||
create_enemy2c(b->pos, hp, kurumi_swirl_draw, kurumi_extra_shield, a + 0.05*I, 800);
|
||||
create_enemy2c(b->pos, hp, kurumi_swirl_draw, kurumi_extra_shield, a - 0.05*I, 800);
|
||||
create_enemy2c(b->pos, hp, kurumi_extra_swirl_visual, kurumi_extra_shield, a + 0.05*I, 800);
|
||||
create_enemy2c(b->pos, hp, kurumi_extra_swirl_visual, kurumi_extra_shield, a - 0.05*I, 800);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1192,7 +1215,7 @@ void kurumi_extra(Boss *b, int time) {
|
|||
if(direction)
|
||||
pos = VIEWPORT_W-creal(pos)+I*cimag(pos);
|
||||
// immune so they don’t get killed while they are still offscreen.
|
||||
create_enemy3c(pos-300*(1-2*direction),ENEMY_IMMUNE,kurumi_extra_fairy_draw,kurumi_extra_fairy,pos,100+20*i+100*(1.1-0.05*global.diff)*I,direction);
|
||||
create_enemy3c(pos-300*(1-2*direction),ENEMY_IMMUNE,kurumi_extra_fairy_visual,kurumi_extra_fairy,pos,100+20*i+100*(1.1-0.05*global.diff)*I,direction);
|
||||
}
|
||||
|
||||
// XXX: maybe add a special sound for this?
|
||||
|
@ -1221,8 +1244,8 @@ void kurumi_extra(Boss *b, int time) {
|
|||
double ofs = VIEWPORT_W * 0.5;
|
||||
complex pos = 0.5 * VIEWPORT_W + I * (VIEWPORT_H - 100);
|
||||
complex targ = 0.5 *VIEWPORT_W + VIEWPORT_H * 0.3 * I;
|
||||
create_enemy1c(pos + ofs, 3300, kurumi_bigfairy_draw, kurumi_extra_bigfairy1, targ + 0.8*ofs);
|
||||
create_enemy1c(pos - ofs, 3300, kurumi_bigfairy_draw, kurumi_extra_bigfairy1, targ - 0.8*ofs);
|
||||
create_enemy1c(pos + ofs, 3300, kurumi_extra_bigfairy_visual, kurumi_extra_bigfairy1, targ + 0.8*ofs);
|
||||
create_enemy1c(pos - ofs, 3300, kurumi_extra_bigfairy_visual, kurumi_extra_bigfairy1, targ - 0.8*ofs);
|
||||
}
|
||||
}
|
||||
if((t == length-20 && global.diff == D_Easy)|| b->current->hp < shieldlimit) {
|
||||
|
|
|
@ -306,7 +306,11 @@ int stage5_explosion(Enemy *e, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void iku_slave_draw(Enemy *e, int t) {
|
||||
void iku_slave_visual(Enemy *e, int t, bool render) {
|
||||
if(render) {
|
||||
return;
|
||||
}
|
||||
|
||||
complex offset = (frand()-0.5)*10 + (frand()-0.5)*10.0*I;
|
||||
|
||||
if(e->args[2] && !(t % 5)) {
|
||||
|
@ -338,7 +342,7 @@ void iku_mid_intro(Boss *b, int t) {
|
|||
b->pos += -1-7.0*I+10*t*(cimag(b->pos)<-200);
|
||||
|
||||
FROM_TO(90, 110, 10) {
|
||||
create_enemy3c(b->pos, ENEMY_IMMUNE, iku_slave_draw, stage5_explosion, -2-0.5*_i+I*_i, _i == 1,1);
|
||||
create_enemy3c(b->pos, ENEMY_IMMUNE, iku_slave_visual, stage5_explosion, -2-0.5*_i+I*_i, _i == 1,1);
|
||||
}
|
||||
|
||||
AT(960)
|
||||
|
@ -853,8 +857,12 @@ Enemy* iku_extra_find_next_slave(complex from, double playerbias) {
|
|||
return nearest;
|
||||
}
|
||||
|
||||
void iku_extra_slave_draw(Enemy *e, int t) {
|
||||
iku_slave_draw(e, t);
|
||||
void iku_extra_slave_visual(Enemy *e, int t, bool render) {
|
||||
iku_slave_visual(e, t, render);
|
||||
|
||||
if(render) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(e->args[2] && !(t % 5)) {
|
||||
complex offset = (frand()-0.5)*30 + (frand()-0.5)*20.0*I;
|
||||
|
@ -1056,7 +1064,7 @@ void iku_extra(Boss *b, int t) {
|
|||
for(i = 0; i < cnt; ++i) {
|
||||
for(j = 0; j < cnt; ++j) {
|
||||
complex epos = step * (0.5 + i) + (step * j + 125) * I;
|
||||
create_enemy4c(b->pos, ENEMY_IMMUNE, iku_extra_slave_draw, iku_extra_slave, epos, 0, 0, 1);
|
||||
create_enemy4c(b->pos, ENEMY_IMMUNE, iku_extra_slave_visual, iku_extra_slave, epos, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,7 +194,11 @@ int scythe_mid(Enemy *e, int t) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void Scythe(Enemy *e, int t) {
|
||||
void Scythe(Enemy *e, int t, bool render) {
|
||||
if(render) {
|
||||
return;
|
||||
}
|
||||
|
||||
PARTICLE(
|
||||
.texture_ptr = get_tex("stage6/scythe"),
|
||||
.pos = e->pos+I*6*sin(global.frames/25.0),
|
||||
|
@ -580,11 +584,27 @@ void elly_maxwell(Boss *b, int t) {
|
|||
|
||||
}
|
||||
|
||||
void Baryon(Enemy *e, int t) {
|
||||
void Baryon(Enemy *e, int t, bool render) {
|
||||
Enemy *n;
|
||||
|
||||
float alpha = 1 - 0.8/(exp((cabs(global.plr.pos-e->pos)-100)/10)+1);
|
||||
|
||||
if(!render) {
|
||||
if(!(t % 10) && global.boss && cabs(e->pos - global.boss->pos) > 2) {
|
||||
PARTICLE(
|
||||
.texture = "stain",
|
||||
.pos = e->pos+10*frand()*cexp(2.0*I*M_PI*frand()),
|
||||
.color = rgb(0, 1*alpha, 0.7*alpha),
|
||||
.draw_rule = Fade,
|
||||
.rule = timeout,
|
||||
.args = { 50 },
|
||||
.angle = 2*M_PI*frand(),
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
glColor4f(1.0,1.0,1.0,alpha);
|
||||
draw_texture(creal(e->pos), cimag(e->pos), "stage6/baryon");
|
||||
glColor4f(1.0,1.0,1.0,1.0);
|
||||
|
@ -603,26 +623,32 @@ void Baryon(Enemy *e, int t) {
|
|||
draw_quad();
|
||||
glPopMatrix();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// PARTICLE("flare", e->pos+40*frand()*cexp(2.0*I*M_PI*frand()), rgb(0, 1, 1), GrowFadeAdd, timeout_linear, 50, 1-I);
|
||||
void BaryonCenter(Enemy *e, int t, bool render) {
|
||||
Enemy *l[2];
|
||||
int i;
|
||||
|
||||
if(!(t % 10) && global.boss && cabs(e->pos - global.boss->pos) > 2) {
|
||||
PARTICLE(
|
||||
.texture = "stain",
|
||||
.pos = e->pos+10*frand()*cexp(2.0*I*M_PI*frand()),
|
||||
.color = rgb(0, 1*alpha, 0.7*alpha),
|
||||
if(!render) {
|
||||
complex p = e->pos+40*frand()*cexp(2.0*I*M_PI*frand());
|
||||
|
||||
PARTICLE("flare", p, rgb(0.0, 1.0, 1.0),
|
||||
.draw_rule = GrowFade,
|
||||
.rule = timeout_linear,
|
||||
.args = { 50, 1-I },
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
|
||||
PARTICLE("stain", p, rgb(0.0, 1.0, 0.2),
|
||||
.draw_rule = Fade,
|
||||
.rule = timeout,
|
||||
.args = { 50 },
|
||||
.angle = 2*M_PI*frand(),
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void BaryonCenter(Enemy *e, int t) {
|
||||
Enemy *l[2];
|
||||
int i;
|
||||
return;
|
||||
}
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
|
||||
|
@ -634,7 +660,6 @@ void BaryonCenter(Enemy *e, int t) {
|
|||
draw_texture(creal(e->pos), cimag(e->pos), "stage6/baryon");
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
||||
l[0] = REF(creal(e->args[1]));
|
||||
l[1] = REF(cimag(e->args[1]));
|
||||
|
||||
|
@ -653,23 +678,6 @@ void BaryonCenter(Enemy *e, int t) {
|
|||
|
||||
}
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
complex p = e->pos+40*frand()*cexp(2.0*I*M_PI*frand());
|
||||
|
||||
PARTICLE("flare", p, rgb(0.0, 1.0, 1.0),
|
||||
.draw_rule = GrowFade,
|
||||
.rule = timeout_linear,
|
||||
.args = { 50, 1-I },
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
|
||||
PARTICLE("stain", p, rgb(0.0, 1.0, 0.2),
|
||||
.draw_rule = Fade,
|
||||
.rule = timeout,
|
||||
.args = { 50 },
|
||||
.angle = 2*M_PI*frand(),
|
||||
.flags = PFLAG_DRAWADD,
|
||||
);
|
||||
}
|
||||
|
||||
int baryon_unfold(Enemy *e, int t) {
|
||||
|
@ -764,7 +772,7 @@ void elly_unbound(Boss *b, int t) {
|
|||
static void set_baryon_rule(EnemyLogicRule r) {
|
||||
Enemy *e;
|
||||
for(e = global.enemies; e; e = e->next) {
|
||||
if(e->draw_rule == Baryon) {
|
||||
if(e->visual_rule == Baryon) {
|
||||
e->birthtime = global.frames;
|
||||
e->logic_rule = r;
|
||||
}
|
||||
|
@ -975,7 +983,7 @@ int baryon_broglie(Enemy *e, int t) {
|
|||
Enemy *master = NULL;
|
||||
|
||||
for(Enemy *en = global.enemies; en; en = en->next) {
|
||||
if(en->draw_rule == Baryon) {
|
||||
if(en->visual_rule == Baryon) {
|
||||
master = en;
|
||||
break;
|
||||
}
|
||||
|
@ -1237,7 +1245,7 @@ static int ricci_proj(Projectile *p, int t) {
|
|||
double influence = 0;
|
||||
|
||||
for(e = global.enemies; e; e = e->next, i++) {
|
||||
if(e->draw_rule != Baryon) {
|
||||
if(e->visual_rule != Baryon) {
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -28,5 +28,5 @@ void elly_curvature(Boss*, int);
|
|||
void stage6_events(void);
|
||||
Boss* stage6_spawn_elly(complex pos);
|
||||
|
||||
void Scythe(Enemy *e, int t);
|
||||