redo masterspark

This commit is contained in:
laochailan 2017-11-12 16:15:12 +01:00
parent e7b1b9f22a
commit 16f443e54c
No known key found for this signature in database
GPG key ID: 49BE98017AFBC943
15 changed files with 1417 additions and 58 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 KiB

View file

@ -0,0 +1,25 @@
#version 110
varying vec4 texc;
void main(void) {
gl_Position = ftransform();
gl_FrontColor = gl_Color;
texc = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
%% -- FRAG
#version 110
uniform float t;
varying vec4 texc;
void main(void) {
vec2 r = vec2(texc.x-0.5,1.0-texc.y);
float f = abs(r.x)-0.4*pow(r.y,0.3);
vec3 clr = vec3(0.8+0.2*sin(r.x),0.8+0.2*cos(r.y-t*0.1),0.8+0.2*sin((r.x-r.y)*0.7+t*0.2));
gl_FragColor = vec4(clr,step(f+0.01*sin(r.y*30.-t*0.7)*(1.-1./(t+1.)),-0.05))+vec4(1.)*step(f,-0.1-0.2/(1.+t*0.1));
}

View file

@ -57,6 +57,7 @@ typedef void (*PlayerModeFreeProc)(Player *plr);
typedef void (*PlayerModeThinkProc)(Player *plr);
typedef void (*PlayerModeShotProc)(Player *plr);
typedef void (*PlayerModeBombProc)(Player *plr);
typedef void (*PlayerModeBombBgProc)(Player *plr);
typedef void (*PlayerModePowerProc)(Player *plr, short npow);
typedef double (*PlayerModeSpeedModProc)(Player *plr, double speed);
typedef void (*PlayerModePreloadProc)(void);
@ -72,6 +73,7 @@ typedef struct PlayerMode {
PlayerModeThinkProc think;
PlayerModeShotProc shot;
PlayerModeBombProc bomb;
PlayerModeBombBgProc bombbg;
PlayerModePowerProc power;
PlayerModeSpeedModProc speed_mod;
PlayerModePreloadProc preload;

View file

@ -281,61 +281,33 @@ static int marisa_laser_slave(Enemy *e, int t) {
return 1;
}
static void masterspark_ring_draw(complex base, int t, float fade) {
glPushMatrix();
if(t < 1) {
// prevent division by zero
t = 1;
}
glTranslatef(creal(base), cimag(base)-t*t*0.4, 0);
float f = sqrt(t/500.0)*1200;
glColor4f(1,1,1,fade*20.0/t);
Texture *tex = get_tex("masterspark_ring");
glScalef(f/tex->w, 1-tex->h/f,0);
draw_texture_p(0,0,tex);
glPopMatrix();
}
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);
float fade = 1;
glPushMatrix();
float angle = 9 - t/e->args[0]*6.0, fade = 1;
if(t < creal(e->args[0]/6))
if(t < creal(e->args[0]/6)) {
fade = t/e->args[0]*6;
fade = sqrt(fade);
}
if(t > creal(e->args[0])/4*3)
if(t > creal(e->args[0])/4*3) {
fade = 1-t/e->args[0]*4 + 3;
fade *= fade;
}
glColor4f(1,0.85,1,fade);
glTranslatef(creal(global.plr.pos), cimag(global.plr.pos), 0);
glRotatef(-angle,0,0,1);
draw_texture(0, -450, "masterspark");
glColor4f(0.85,1,1,fade);
glRotatef(angle*2,0,0,1);
draw_texture(0, -450, "masterspark");
glColor4f(1,1,1,fade);
glRotatef(-angle,0,0,1);
draw_texture(0, -450, "masterspark");
Shader *mshader = get_shader("masterspark");
glUseProgram(mshader->prog);
glUniform1f(uniloc(mshader,"t"),t);
glPushMatrix();
glTranslatef(creal(global.plr.pos),cimag(global.plr.pos)-40-VIEWPORT_H/2,0);
glScalef(fade*400,VIEWPORT_H,1);
draw_quad();
glPopMatrix();
// glColor4f(0.9,1,1,fade*0.8);
for(int i = 0; i < 8; i++)
masterspark_ring_draw(global.plr.pos - 50.0*I, t%20 + 10*i, fade);
glColor4f(1,1,1,1);
glUseProgram(0);
}
static int masterspark(Enemy *e, int t) {
@ -344,9 +316,15 @@ static int masterspark(Enemy *e, int t) {
return 1;
}
t = player_get_bomb_progress(&global.plr, NULL) * (e->args[0] / BOMB_RECOVERY);
t = player_get_bomb_progress(&global.plr, NULL);
if(t%2==0 && t < BOMB_RECOVERY*3/4) {
complex dir = -cexp(M_PI*I*frand());
Color c = rgb(0.7+0.3*sin(t*0.1),0.7+0.3*cos(t*0.1),0.7+0.3*cos(t*0.01));
PARTICLE("maristar_orbit",global.plr.pos+40*dir,c,timeout_linear,{50, 10*dir-10*I,3},nfrand(),PFLAG_DRAWADD,GrowFade);
PARTICLE("smoke",global.plr.pos-40*I,rgb(0.9,1,1),timeout_linear,{50, -5*dir,3},nfrand(),PFLAG_DRAWADD,GrowFade);
}
if(t >= creal(e->args[0]) || global.frames - global.plr.recovery > 0) {
if(t >= BOMB_RECOVERY || global.frames - global.plr.recovery > 0) {
global.shake_view = 0;
return ACTION_DESTROY;
}
@ -354,6 +332,21 @@ static int masterspark(Enemy *e, int t) {
return 1;
}
static void marisa_laser_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.8*fade);
fill_screen(sin(t*0.001),t*0.01*(1+t*0.01),1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
static void marisa_laser_bomb(Player *plr) {
play_sound("bomb_marisa_a");
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_BOMB, masterspark_visual, masterspark, 280,0,0,0);
@ -455,6 +448,7 @@ static void marisa_laser_preload(void) {
"proj/marisa",
"masterspark",
"masterspark_ring",
"marisa_bombbg",
"part/marisa_laser0",
"part/marisa_laser1",
"part/magic_star",
@ -475,6 +469,7 @@ PlayerMode plrmode_marisa_a = {
.shot_mode = PLR_SHOT_MARISA_LASER,
.procs = {
.bomb = marisa_laser_bomb,
.bombbg = marisa_laser_bombbg,
.shot = marisa_laser_shot,
.power = marisa_laser_power,
.speed_mod = marisa_laser_speed_mod,

View file

@ -0,0 +1,484 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
*/
#include "global.h"
#include "plrmodes.h"
#include "marisa.h"
// args are pain
static float global_magicstar_alpha;
static void draw_laser_beam(complex src, complex dst, double size, double step, double t, Texture *tex, int u_length) {
complex dir = dst - src;
complex center = (src + dst) * 0.5;
glPushMatrix();
glTranslatef(creal(center), cimag(center), 0);
glRotatef(180/M_PI*carg(dir), 0, 0, 1);
glScalef(cabs(dir), size, 1);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(-cimag(src) / step + t, 0, 0);
glScalef(cabs(dir) / step, 1, 1);
glMatrixMode(GL_MODELVIEW);
glBindTexture(GL_TEXTURE_2D, tex->gltex);
glUniform1f(u_length, cabs(dir) / step);
draw_quad();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
static complex trace_laser(complex origin, complex vel, int damage) {
int col;
complex target = trace_projectile(
origin, 28*(1+I), linear, 0, vel, 0, 0, 0, PlrProj + damage, &col
);
if(col) {
tsrand_fill(3);
PARTICLE(
.texture = "flare",
.pos = target,
.rule = timeout_linear,
.draw_rule = Shrink,
.args = {
3 + 5 * afrand(2),
(2+afrand(0)*6)*cexp(I*M_PI*2*afrand(1))
},
.type = PlrProj,
);
}
return target;
}
static float set_alpha(int u_alpha, float a) {
if(a) {
glUniform1f(u_alpha, a);
}
return a;
}
static float set_alpha_dimmed(int u_alpha, float a) {
return set_alpha(u_alpha, a * a * 0.5);
}
static void draw_magic_star(complex pos, double a, Color c1, Color c2) {
if(a <= 0) {
return;
}
Color mul = rgba(1, 1, 1, a);
c1 = multiply_colors(c1, mul);
c2 = multiply_colors(c2, mul);
Texture *tex = get_tex("part/magic_star");
Shader *shader = recolor_get_shader();
ColorTransform ct;
glUseProgram(shader->prog);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glPushMatrix();
glTranslatef(creal(pos), cimag(pos), -1);
glScalef(0.25, 0.25, 1);
glPushMatrix();
static_clrtransform_bullet(c1, &ct);
recolor_apply_transform(&ct);
glRotatef(global.frames * 3, 0, 0, 1);
draw_texture_p(0, 0, tex);
glPopMatrix();
glPushMatrix();
static_clrtransform_bullet(c2, &ct);
recolor_apply_transform(&ct);
glRotatef(global.frames * -3, 0, 0, 1);
draw_texture_p(0, 0, tex);
glPopMatrix();
glPopMatrix();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(0);
}
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] * global_magicstar_alpha;
draw_magic_star(e->pos, 0.75 * star_alpha,
rgb(1.0, 0.1, 0.1),
rgb(0.0, 0.1, 1.1)
);
marisa_common_slave_visual(e, t, render);
if(laser_alpha <= 0) {
return;
}
glColor4f(1, 1, 1, laser_alpha);
glPushMatrix();
glTranslatef(creal(e->args[3]), cimag(e->args[3]), 0);
draw_texture(0, 0, "part/lasercurve");
glPopMatrix();
glColor4f(1, 1, 1, 1);
}
static void marisa_laser_fader_visual(Enemy *e, int t, bool render) {
}
static float get_laser_alpha(Enemy *e, float a) {
if(e->visual_rule == marisa_laser_fader_visual) {
return e->args[1];
}
return min(a, min(1, (global.frames - e->birthtime) * 0.1));
}
#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->visual_rule == marisa_laser_slave_visual)
static void marisa_laser_renderer_visual(Enemy *renderer, int t, bool render) {
if(!render) {
return;
}
double a = creal(renderer->args[0]);
Shader *shader = get_shader("marisa_laser");
int u_clr0 = uniloc(shader, "color0");
int u_clr1 = uniloc(shader, "color1");
int u_clr_phase = uniloc(shader, "color_phase");
int u_clr_freq = uniloc(shader, "color_freq");
int u_alpha = uniloc(shader, "alphamod");
int u_length = uniloc(shader, "length");
// int u_cutoff = uniloc(shader, "cutoff");
Texture *tex0 = get_tex("part/marisa_laser0");
Texture *tex1 = get_tex("part/marisa_laser1");
glUseProgram(shader->prog);
glUniform4f(u_clr0, 1, 1, 1, 0.5);
glUniform4f(u_clr1, 1, 1, 1, 0.8);
glUniform1f(u_clr_phase, -1.5 * t/M_PI);
glUniform1f(u_clr_freq, 10.0);
glBlendFunc(GL_SRC_COLOR, GL_ONE);
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbo.rgba[0].fbo);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0, 0, 0, 1);
glBlendEquation(GL_MAX);
FOR_EACH_SLAVE(e) {
if(set_alpha(u_alpha, get_laser_alpha(e, a))) {
draw_laser_beam(e->pos, e->args[3], 32, 128, -0.02 * t, tex1, u_length);
}
}
glBlendEquation(GL_FUNC_ADD);
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbo.fg[0].fbo);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(0);
draw_fbo_viewport(&resources.fbo.rgba[0]);
glUseProgram(shader->prog);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glUniform4f(u_clr0, 1.0, 0.0, 0.0, 0.5);
glUniform4f(u_clr1, 1.0, 0.0, 0.0, 1.0);
FOR_EACH_SLAVE(e) {
if(set_alpha_dimmed(u_alpha, get_laser_alpha(e, a))) {
draw_laser_beam(e->pos, e->args[3], 40, 128, t * -0.12, tex0, u_length);
}
}
glUniform4f(u_clr0, 0.1, 0.5, 1.0, 2.0);
glUniform4f(u_clr1, 0.1, 0.1, 1.0, 1.0);
FOR_EACH_SLAVE(e) {
if(set_alpha_dimmed(u_alpha, get_laser_alpha(e, a))) {
draw_laser_beam(e->pos, e->args[3], 42, 200, t * -0.03, tex0, u_length);
}
}
glUseProgram(0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
static int marisa_laser_fader(Enemy *e, int t) {
e->args[1] = approach(e->args[1], 0.0, 0.1);
if(creal(e->args[1]) == 0) {
return ACTION_DESTROY;
}
return 1;
}
static Enemy* spawn_laser_fader(Enemy *e, double alpha) {
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]);
}
static int marisa_laser_renderer(Enemy *renderer, int t) {
if(player_should_shoot(&global.plr, true) && renderer->next) {
renderer->args[0] = approach(renderer->args[0], 1.0, 0.2);
renderer->args[1] = approach(renderer->args[1], 1.0, 0.2);
renderer->args[2] = 1;
} else {
if(creal(renderer->args[2])) {
FOR_EACH_REAL_SLAVE(e) {
spawn_laser_fader(e, renderer->args[0]);
}
renderer->args[2] = 0;
}
renderer->args[0] = 0;
renderer->args[1] = approach(renderer->args[1], 0.0, 0.1);
}
return 1;
}
#undef FOR_EACH_SLAVE
#undef FOR_EACH_REAL_SLAVE
static int marisa_laser_slave(Enemy *e, int t) {
if(t == EVENT_DEATH && !global.game_over && global.plr.slaves && creal(global.plr.slaves->args[0])) {
spawn_laser_fader(e, global.plr.slaves->args[0]);
return 1;
}
if(t < 0) {
return 1;
}
e->pos = global.plr.pos + (1 - global.plr.focus/30.0)*e->pos0 + (global.plr.focus/30.0)*e->args[0];
if(player_should_shoot(&global.plr, true)) {
float angle = creal(e->args[2]);
float f = smoothreclamp(global.plr.focus, 0, 30, 0, 1);
f = smoothreclamp(f, 0, 1, 0, 1);
float factor = (1.0 + 0.7 * psin(t/15.0)) * -(1-f) * !!angle;
e->args[3] = trace_laser(e->pos, -5 * cexp(I*(angle*factor + M_PI/2)), creal(e->args[1]));
}
return 1;
}
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);
float fade = 1;
if(t < creal(e->args[0]/6)) {
fade = t/e->args[0]*6;
fade = sqrt(fade);
}
if(t > creal(e->args[0])/4*3) {
fade = 1-t/e->args[0]*4 + 3;
fade *= fade;
}
Shader *mshader = get_shader("masterspark");
glUseProgram(mshader->prog);
glUniform1f(uniloc(mshader,"t"),t);
glPushMatrix();
glTranslatef(creal(global.plr.pos),cimag(global.plr.pos)-40-VIEWPORT_H/2,0);
glScalef(fade*400,VIEWPORT_H,1);
draw_quad();
glPopMatrix();
glUseProgram(0);
}
static int masterspark(Enemy *e, int t) {
if(t == EVENT_BIRTH) {
global.shake_view = 8;
return 1;
}
t = player_get_bomb_progress(&global.plr, NULL);
if(t%2==0 && t < BOMB_RECOVERY*3/4) {
complex dir = -cexp(M_PI*I*frand());
Color c = rgb(0.7+0.3*sin(t*0.1),0.7+0.3*cos(t*0.1),0.7+0.3*cos(t*0.01));
PARTICLE("maristar_orbit",global.plr.pos+40*dir,c,timeout_linear,{50, 10*dir-10*I,3},nfrand(),PFLAG_DRAWADD,GrowFade);
PARTICLE("smoke",global.plr.pos-40*I,rgb(0.9,1,1),timeout_linear,{50, -5*dir,3},nfrand(),PFLAG_DRAWADD,GrowFade);
}
if(t >= BOMB_RECOVERY || global.frames - global.plr.recovery > 0) {
global.shake_view = 0;
return ACTION_DESTROY;
}
return 1;
}
static void marisa_laser_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.8*fade);
fill_screen(sin(t*0.001),t*0.01*(1+t*0.01),1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
static void marisa_laser_bomb(Player *plr) {
play_sound("bomb_marisa_a");
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) {
Enemy *e = plr->slaves, *tmp;
double dmg = 4;
while(e != 0) {
tmp = e;
e = e->next;
if(tmp->logic_rule == marisa_laser_slave) {
delete_enemy(&plr->slaves, tmp);
}
}
if(npow / 100 == 1) {
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_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_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_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);
}
}
static void marisa_laser_power(Player *plr, short npow) {
if(plr->power / 100 == npow / 100) {
return;
}
marisa_laser_respawn_slaves(plr, npow);
}
static void marisa_laser_init(Player *plr) {
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);
}
static void marisa_laser_think(Player *plr) {
Enemy *laser_renderer = plr->slaves;
assert(laser_renderer != NULL);
assert(laser_renderer->logic_rule == marisa_laser_renderer);
if(creal(laser_renderer->args[0]) > 0) {
bool found = false;
for(Projectile *p = global.projs; p && !found; p = p->next) {
if(p->type != EnemyProj) {
continue;
}
for(Enemy *slave = laser_renderer->next; slave; slave = slave->next) {
if(slave->visual_rule == marisa_laser_slave_visual && cabs(slave->pos - p->pos) < 30) {
found = true;
break;
}
}
}
if(found) {
global_magicstar_alpha = approach(global_magicstar_alpha, 0.25, 0.15);
} else {
global_magicstar_alpha = approach(global_magicstar_alpha, 1.00, 0.08);
}
} else {
global_magicstar_alpha = 1.0;
}
}
static double marisa_laser_speed_mod(Player *plr, double speed) {
if(global.frames - plr->recovery < 0) {
speed /= 5.0;
}
return speed;
}
static void marisa_laser_shot(Player *plr) {
marisa_common_shot(plr, 175);
}
static void marisa_laser_preload(void) {
const int flags = RESF_DEFAULT;
preload_resources(RES_TEXTURE, flags,
// "part/marilaser_part0",
// "proj/marilaser",
"proj/marisa",
"masterspark",
"masterspark_ring",
"marisa_bombbg",
"part/marisa_laser0",
"part/marisa_laser1",
"part/magic_star",
NULL);
preload_resources(RES_SHADER, flags,
"marisa_laser",
NULL);
preload_resources(RES_SFX, flags | RESF_OPTIONAL,
"bomb_marisa_a",
NULL);
}
PlayerMode plrmode_marisa_a = {
.name = "Laser Sign",
.character = &character_marisa,
.shot_mode = PLR_SHOT_MARISA_LASER,
.procs = {
.bomb = marisa_laser_bomb,
<<<<<<< HEAD
.shot = marisa_laser_shot,
=======
.bombbg = marisa_laser_bombbg,
.shot = marisa_common_shot,
>>>>>>> redo masterspark
.power = marisa_laser_power,
.speed_mod = marisa_laser_speed_mod,
.preload = marisa_laser_preload,
.init = marisa_laser_init,
.think = marisa_laser_think,
},
};

View file

@ -156,6 +156,21 @@ static void marisa_star_bomb(Player *plr) {
}
}
static void marisa_star_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.6*fade);
fill_screen(0,-t*0.01,1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
static void marisa_star_respawn_slaves(Player *plr, short npow) {
Enemy *e = plr->slaves, *tmp;
double dmg = 56;
@ -223,6 +238,7 @@ PlayerMode plrmode_marisa_b = {
.shot_mode = PLR_SHOT_MARISA_STAR,
.procs = {
.bomb = marisa_star_bomb,
.bombbg = marisa_star_bombbg,
.shot = marisa_star_shot,
.power = marisa_star_power,
.preload = marisa_star_preload,

View file

@ -0,0 +1,251 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
*/
#include "global.h"
#include "plrmodes.h"
#include "marisa.h"
static void marisa_star(Projectile *p, int t) {
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos), 0);
glRotatef(t*10, 0, 0, 1);
ProjDrawCore(p, p->color);
glPopMatrix();
}
static void marisa_star_trail_draw(Projectile *p, int t) {
float s = 1 - t / creal(p->args[0]);
Color clr = derive_color(p->color, CLRMASK_A, rgba(0, 0, 0, s*0.5));
// s = 1 + t / creal(p->args[0]);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos), 0);
// glRotatef(t*10, 0, 0, 1);
glRotatef(p->angle*180/M_PI+90, 0, 0, 1);
glScalef(s, s, 1);
ProjDrawCore(p, clr);
glColor4f(1,1,1,1);
glPopMatrix();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
static void marisa_star_bomb_draw(Projectile *p, int t) {
marisa_star(p, t);
}
static int marisa_star_projectile(Projectile *p, int t) {
float c = 0.3 * psin(t * 0.2);
p->color = rgb(1 - c, 0.7 + 0.3 * psin(t * 0.1), 0.9 + c/3);
int r = accelerated(p, t);
p->angle = t * 10;
PARTICLE(
.texture_ptr = get_tex("proj/maristar"),
.pos = p->pos,
.color = p->color,
.rule = timeout,
.args = { 8 },
.draw_rule = marisa_star_trail_draw,
.type = PlrProj,
.angle = p->angle,
.flags = PFLAG_DRAWADD,
);
if(t == EVENT_DEATH) {
PARTICLE(
.texture_ptr = get_tex("proj/maristar"),
.pos = p->pos,
.color = p->color,
.rule = timeout,
.draw_rule = GrowFade,
.args = { 40, 2 },
.type = PlrProj,
.angle = frand() * 2 * M_PI,
.flags = PFLAG_DRAWADD,
);
}
return r;
}
static int marisa_star_slave(Enemy *e, int t) {
double focus = global.plr.focus/30.0;
for(int i = 0; i < 3; ++i) {
if(player_should_shoot(&global.plr, true) && !((global.frames+2*i) % 15)) {
complex v = e->args[1] * 2;
complex a = e->args[2];
v = creal(v) * (1 - 5 * focus) + I * cimag(v) * (1 - 2.5 * focus);
a = creal(a) * focus * -0.0525 + I * cimag(a) * 2;
v *= cexp(I*i*M_PI/20*sign(v));
a *= cexp(I*i*M_PI/20*sign(v)*focus);
PROJECTILE(
.texture_ptr = get_tex("proj/maristar"),
.pos = e->pos,
.color = rgb(1.0, 0.5, 1.0),
.rule = marisa_star_projectile,
// .draw_rule = marisa_star,
.args = { v, a },
.type = PlrProj + e->args[3],
.color_transform_rule = proj_clrtransform_particle,
);
}
}
e->pos = global.plr.pos + (1 - focus)*e->pos0 + focus*e->args[0];
return 1;
}
static int marisa_star_orbit_logic(void *v, int t, double speed) {
Projectile *p = v;
float r = cabs(p->pos0 - p->pos);
p->args[1] = (0.5e5-t*t)*cexp(I*carg(p->pos0 - p->pos))/(r*r);
p->args[0] += p->args[1]*0.2;
p->pos += p->args[0];
PARTICLE("maristar_orbit", p->pos, 0, timeout, { 40 / speed },
.draw_rule = GrowFade,
.type = PlrProj,
.flags = PFLAG_DRAWADD,
);
return 1;
}
static int marisa_star_orbit(Projectile *p, int t) { // a[0]: x' a[1]: x''
if(t == 0) {
p->pos0 = global.plr.pos;
}
if(t < 0) {
return 1;
}
if(global.frames - global.plr.recovery > 0) {
return ACTION_DESTROY;
}
return player_run_bomb_logic(&global.plr, p, &p->args[3], marisa_star_orbit_logic);
}
static void marisa_star_bomb(Player *plr) {
play_sound("bomb_marisa_b");
for(int i = 0; i < 20; i++) {
float r = frand()*40 + 100;
float phi = frand()*2*M_PI;
PARTICLE("maristar_orbit", plr->pos + r*cexp(I*phi), 0, marisa_star_orbit,
.draw_rule = marisa_star_bomb_draw,
.args = { I*r*cexp(I*(phi+frand()*0.5))/10 },
.type = PlrProj,
);
}
}
static void marisa_star_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.6*fade);
fill_screen(0,-t*0.01,1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
static void marisa_star_respawn_slaves(Player *plr, short npow) {
Enemy *e = plr->slaves, *tmp;
double dmg = 56;
while(e != 0) {
tmp = e;
e = e->next;
if(tmp->hp == ENEMY_IMMUNE)
delete_enemy(&plr->slaves, tmp);
}
if(npow / 100 == 1) {
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_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_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_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);
}
}
static void marisa_star_power(Player *plr, short npow) {
if(plr->power / 100 == npow / 100) {
return;
}
marisa_star_respawn_slaves(plr, npow);
}
static void marisa_star_init(Player *plr) {
marisa_star_respawn_slaves(plr, plr->power);
}
static void marisa_star_shot(Player *plr) {
int p = plr->power / 100;
marisa_common_shot(plr, 175 - 10*p);
}
static void marisa_star_preload(void) {
const int flags = RESF_DEFAULT;
preload_resources(RES_TEXTURE, flags,
"proj/marisa",
"proj/maristar",
"part/maristar_orbit",
NULL);
preload_resources(RES_SFX, flags | RESF_OPTIONAL,
"bomb_marisa_b",
NULL);
}
PlayerMode plrmode_marisa_b = {
.name = "Star Sign",
.character = &character_marisa,
.shot_mode = PLR_SHOT_MARISA_STAR,
.procs = {
.bomb = marisa_star_bomb,
<<<<<<< HEAD
.shot = marisa_star_shot,
=======
.bombbg = marisa_star_bombbg,
.shot = marisa_common_shot,
>>>>>>> redo masterspark
.power = marisa_star_power,
.preload = marisa_star_preload,
.init = marisa_star_init,
},
};

View file

@ -85,6 +85,21 @@ void youmu_common_shot(Player *plr) {
}
}
void youmu_common_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.6*fade);
fill_screen(0,-t*0.01,1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
void youmu_common_draw_proj(Projectile *p, Color c, float scale) {
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos), 0);

113
src/plrmodes/youmu.c.orig Normal file
View file

@ -0,0 +1,113 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
*/
#include "global.h"
#include "plrmodes.h"
PlayerCharacter character_youmu = {
.id = PLR_CHAR_YOUMU,
.lower_name = "youmu",
.proper_name = "Yōmu",
.full_name = "Konpaku Yōmu",
.title = "Half-Phantom Girl",
.dialog_sprite_name = "dialog/youmu",
.player_sprite_name = "youmu",
.ending = {
.good = good_ending_youmu,
.bad = bad_ending_youmu,
},
};
int youmu_common_particle_spin(Projectile *p, int t) {
int i = timeout_linear(p, t);
if(t < 0)
return 1;
p->args[3] += 0.06;
p->angle = p->args[3];
return i;
}
void youmu_common_particle_slice_draw(Projectile *p, int t) {
float f = p->args[1]/p->args[0]*20.0;
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos),0);
glRotatef(p->angle/M_PI*180,0,0,1);
glScalef(f,1,1);
draw_texture(0,0,"part/youmu_slice");
ProjDrawCore(p, p->color);
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");
}
if(!(global.frames % 6)) {
Color c = rgb(1, 1, 1);
PROJECTILE("youmu", plr->pos + 10 - I*20, c, linear, { -20.0*I },
.type = PlrProj+120,
.color_transform_rule = proj_clrtransform_particle,
);
PROJECTILE("youmu", plr->pos - 10 - I*20, c, linear, { -20.0*I },
.type = PlrProj+120,
.color_transform_rule = proj_clrtransform_particle,
);
}
}
<<<<<<< HEAD
void youmu_common_draw_proj(Projectile *p, Color c, float scale) {
glPushMatrix();
glTranslatef(creal(p->pos), cimag(p->pos), 0);
glRotatef(p->angle*180/M_PI+90, 0, 0, 1);
glScalef(scale, scale, 1);
ProjDrawCore(p, c);
glPopMatrix();
}
=======
void youmu_common_bombbg(Player *plr) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glColor4f(1,1,1,0.6*fade);
fill_screen(0,-t*0.01,1,"marisa_bombbg");
glColor4f(1,1,1,1);
}
>>>>>>> redo masterspark

View file

@ -19,3 +19,4 @@ 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);
void youmu_common_draw_proj(Projectile *p, Color c, float scale);
void youmu_common_bombbg(Player *plr);

25
src/plrmodes/youmu.h.orig Normal file
View file

@ -0,0 +1,25 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
*/
#pragma once
#include "plrmodes.h"
#include "youmu_a.h"
#include "youmu_b.h"
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);
<<<<<<< HEAD
void youmu_common_draw_proj(Projectile *p, Color c, float scale);
=======
void youmu_common_bombbg(Player *plr);
>>>>>>> redo masterspark

View file

@ -429,6 +429,7 @@ PlayerMode plrmode_youmu_a = {
.shot_mode = PLR_SHOT_YOUMU_MIRROR,
.procs = {
.bomb = youmu_mirror_bomb,
.bombbg = youmu_common_bombbg,
.shot = youmu_mirror_shot,
.init = youmu_mirror_init,
.preload = youmu_mirror_preload,

441
src/plrmodes/youmu_a.c.orig Normal file
View file

@ -0,0 +1,441 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2017, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2017, Andrei Alexeyev <akari@alienslab.net>.
*/
#include "global.h"
#include "plrmodes.h"
#include "youmu.h"
static Color myon_color(float f, float a) {
// return rgba(0.8+0.2*f, 0.9-0.4*sqrt(f), 1.0-0.2*f*f, a);
// return rgba(0.8+0.2*f, 0.9-0.4*sqrt(f), 1.0-0.4*f*f, a);
return rgba(0.8+0.2*f, 0.9-0.4*sqrt(f), 1.0-0.35*f*f, a);
}
static int myon_particle_rule(Projectile *p, int t) {
if(t >= creal(p->args[0])) {
return ACTION_DESTROY;
}
if(t < 0) {
return 1;
}
p->pos += p->args[1];
p->angle += 0.03 * (1 - 2 * (p->birthtime & 1));
p->color = derive_color(approach_color(p->color, myon_color(0.5, 0), 0.04), CLRMASK_A, p->color);
return 1;
}
static complex myon_tail_dir(void) {
double angle = carg(global.plr.slaves->args[1]);
complex dir = cexp(I*(0.1 * sin(global.frames * 0.05) + angle));
float f = abs(global.plr.focus) / 30.0;
return f * f * dir;
}
static int myon_flare_particle_rule(Projectile *p, int t) {
if(t < 0) {
return 1;
}
// wiggle wiggle
p->pos += 0.05 * (global.plr.slaves->pos - p->pos) * cexp(I * sin((t - global.frames * 2) * 0.1) * M_PI/8);
p->args[1] = 3 * myon_tail_dir();
p->color = derive_color(p->color, CLRMASK_A, rgba(1, 1, 1, pow(1 - min(1, t / p->args[0]), 2)));
return myon_particle_rule(p, t);
}
static void myon_draw_trail(Projectile *p, int t) {
float fadein = clamp(t/10.0, p->args[3], 1);
float s = min(1, 1 - t / p->args[0]);
float a = color_component(p->color, CLR_A) * fadein;
Color c = derive_color(p->color, CLRMASK_A, rgba(0, 0, 0, a * s * s));
youmu_common_draw_proj(p, c, fadein * (2-s) * p->args[2]);
}
static void spawn_stardust(complex pos, Color clr, int timeout, complex v) {
PARTICLE(
.texture = "stardust",
.pos = pos+5*frand()*cexp(2.0*I*M_PI*frand()),
.color = clr,
.draw_rule = myon_draw_trail,
.rule = myon_particle_rule,
.args = { timeout, v, 0.2 + 0.1 * frand(), 1 },
.type = PlrProj,
.angle = M_PI*2*frand(),
.flags = PFLAG_DRAWADD,
);
}
static void myon_spawn_trail(Enemy *e, int t) {
float a = global.frames * 0.07;
complex pos = e->pos + 3 * (cos(a) + I * sin(a));
complex stardust_v = 3 * myon_tail_dir() * cexp(I*M_PI/16*sin(1.33*t));
float f = abs(global.plr.focus) / 30.0;
stardust_v = f * stardust_v + (1 - f) * -I;
if(player_should_shoot(&global.plr, true)) {
PARTICLE(
.texture = "smoke",
.pos = pos+10*frand()*cexp(2.0*I*M_PI*frand()),
.color = myon_color(f, (1 + f) * 0.05),
.draw_rule = myon_draw_trail,
.rule = myon_particle_rule,
.args = { 60, -I*0.0*cexp(I*M_PI/16*sin(t)), -0.2, 0 },
.flags = PFLAG_DRAWADD,
.type = PlrProj,
.angle = M_PI*2*frand(),
);
PARTICLE(
.texture = "flare",
.pos = pos+5*frand()*cexp(2.0*I*M_PI*frand()),
.color = rgba(1, 1, 1, 0.2),
.draw_rule = Shrink,
.rule = myon_particle_rule,
.args = { 10, cexp(I*M_PI*2*frand())*0.5, 0.2, 0 },
.flags = PFLAG_DRAWADD,
.type = PlrProj,
.angle = M_PI*2*frand(),
);
}
PARTICLE(
.texture = "myon",
.color = myon_color(f, 0.5),
.pos = pos,
.rule = myon_flare_particle_rule,
.args = { 40, f * stardust_v },
.draw_rule = Shrink,
.type = PlrProj,
.angle = M_PI*2*frand(),
);
spawn_stardust(pos, rgba(1, 1, 1, 0.1), 60, stardust_v);
}
static void myon_draw_proj_trail(Projectile *p, int t) {
float time_progress = t / p->args[0];
float s = 2 * time_progress;
float a = color_component(p->color, CLR_A) * min(1, s) * (1 - time_progress);
Color c = derive_color(p->color, CLRMASK_A, rgba(0, 0, 0, a));
youmu_common_draw_proj(p, c, s * p->args[2]);
}
static int myon_proj(Projectile *p, int t) {
if(t < 0) {
return 1;
}
linear(p, t);
//p->pos = global.plr.slaves->pos - global.plr.slaves->args[0] / cabs(global.plr.slaves->args[0]) * t * cabs(p->args[0]);
//p->angle = carg(-global.plr.slaves->args[0]);
// spawn_stardust(p->pos, multiply_colors(p->color, myon_color(abs(global.plr.focus) / 30.0, 0.1)), 20, p->args[0]*0.1);
PARTICLE(
.texture = "boss_shadow",
.pos = p->pos,
.color = derive_color(p->color, CLRMASK_A, rgba(0, 0, 0, 0.075)),
.draw_rule = myon_draw_proj_trail,
.rule = timeout_linear,
.args = { 10, p->args[0]*0.8, 0.6, 0 },
.flags = PFLAG_DRAWADD,
.type = PlrProj,
.angle = p->angle,
);
return 1;
}
static void myon_proj_draw(Projectile *p, int t) {
float a = 1 - pow(1 - min(1, t / 10.0), 2);
Color c = multiply_colors(p->color, rgba(1, 1, 1, a));
youmu_common_draw_proj(p, c, 1);
}
static void myon_proj_clr_transform(Projectile *p, int t, Color c, ColorTransform *out) {
memcpy(out, (&(ColorTransform) {
.R[1] = rgba(1, 1, 1, 0),
.B[1] = multiply_colors(c, c) & ~CLRMASK_A,
.A[1] = c & CLRMASK_A,
}), sizeof(ColorTransform));
}
static Projectile* youmu_mirror_myon_proj(char *tex, complex pos, double speed, double angle, double aoffs, double upfactor, int dmg) {
complex dir = cexp(I*(M_PI/2 + aoffs)) * upfactor + cexp(I * (angle + aoffs)) * (1 - upfactor);
dir = dir / cabs(dir);
// float f = ((global.plr.inputflags & INFLAG_FOCUS) == INFLAG_FOCUS);
float f = smoothreclamp(abs(global.plr.focus) / 30.0, 0, 1, 0, 1);
Color c, intermediate = rgb(1.0, 1.0, 1.0);
if(f < 0.5) {
c = mix_colors(
intermediate,
rgb(0.4, 0.6, 0.6),
f * 2
);
} else {
c = mix_colors(
myon_color(f, 1),
intermediate,
(f - 0.5) * 2
);
}
return PROJECTILE(
.color = c, // mix_colors(myon_color(f, 1), rgb(0.6, 0.8, 0.7), f),
.texture = tex,
.pos = pos,
.rule = myon_proj,
.args = { speed*dir },
.draw_rule = myon_proj_draw,
.type = PlrProj+dmg,
// .flags = PFLAG_DRAWSUB,
.color_transform_rule = myon_proj_clr_transform,
);
}
static int youmu_mirror_myon(Enemy *e, int t) {
if(t == EVENT_BIRTH)
e->pos = e->pos0 + global.plr.pos;
if(t < 0)
return 1;
myon_spawn_trail(e, t);
Player *plr = &global.plr;
float rad = cabs(e->pos0);
double nfocus = plr->focus / 30.0;
if(!(plr->inputflags & INFLAG_SHOT)) {
nfocus = 0.0;
e->pos0 = -rad * I;
} else if(!(plr->inputflags & INFLAG_FOCUS)) {
if((plr->inputflags & INFLAGS_MOVE)) {
e->pos0 = rad * -plr->lastmovedir;
} else {
e->pos0 = e->pos - plr->pos;
e->pos0 *= rad / cabs(e->pos0);
}
}
complex target = plr->pos + e->pos0;
complex v = cexp(I*carg(target - e->pos)) * min(10, 0.07 * max(0, cabs(target - e->pos) - VIEWPORT_W * 0.5 * nfocus));
float s = sign(creal(e->pos) - creal(global.plr.pos));
if(!s) {
s = sign(sin(t/10.0));
}
float rot = clamp(0.005 * cabs(global.plr.pos - e->pos) - M_PI/6, 0, M_PI/8);
v *= cexp(I*rot*s);
e->pos += v;
if(!(plr->inputflags & INFLAG_SHOT) || !(plr->inputflags & INFLAG_FOCUS)) {
e->args[0] = plr->pos - e->pos;
}
e->args[1] += (e->args[0] - e->args[1]) * 0.1;
if(player_should_shoot(&global.plr, true) && global.plr.deathtime >= -1) {
int v1 = -10;
int v2 = -10;
double r1 = (psin(global.frames * 2.0) * 0.5 + 0.5) * 0.1;
double r2 = (psin(global.frames * 1.2) * 0.5 + 0.5) * 0.1;
double a = carg(e->args[0]);
double f = smoothreclamp(0.5 + 0.5 * (1.0 - nfocus), 0, 1, 0, 1);
double u = 0; // smoothreclamp(1 - nfocus, 0, 1, 0, 1);
r1 *= f;
r2 *= f;
int p = plr->power / 100;
int dmg_center = 180 - rint(160 * (1 - pow(1 - 0.25 * p, 2)));
int dmg_side = 41 - 3 * p;
if(plr->power >= 100 && !((global.frames+0) % 6)) {
youmu_mirror_myon_proj("youmu", e->pos, v2, a, r1*1, u, dmg_side);
youmu_mirror_myon_proj("youmu", e->pos, v2, a, -r1*1, u, dmg_side);
}
if(plr->power >= 200 && !((global.frames+3) % 6)) {
youmu_mirror_myon_proj("youmu", e->pos, v1, a, r2*2, 0, dmg_side);
youmu_mirror_myon_proj("youmu", e->pos, v1, a, -r2*2, 0, dmg_side);
}
if(plr->power >= 300 && !((global.frames+0) % 6)) {
youmu_mirror_myon_proj("youmu", e->pos, v2, a, r1*3, 0, dmg_side);
youmu_mirror_myon_proj("youmu", e->pos, v2, a, -r1*3, 0, dmg_side);
}
if(plr->power >= 400 && !((global.frames+3) % 6)) {
youmu_mirror_myon_proj("youmu", e->pos, v1, a, r2*4, u, dmg_side);
youmu_mirror_myon_proj("youmu", e->pos, v1, a, -r2*4, u, dmg_side);
}
if(!((global.frames+3) % 6)) {
youmu_mirror_myon_proj("youmu", e->pos, v1, a, 0, 0, dmg_center);
}
}
return 1;
}
static int youmu_mirror_self_proj(Projectile *p, int t) {
if(t < 0) {
return 1;
}
complex v0 = p->args[0];
complex v1 = p->args[1];
double f = creal(p->args[2]) ? clamp(t / p->args[2], 0, 1) : 1;
complex v = v1*f + v0*(1-f);
complex diff = p->pos0 + v * t - p->pos;
p->pos += diff;
p->angle = carg(diff ? diff : v);
return 1;
}
static Projectile* youmu_mirror_self_shot(Player *plr, complex ofs, complex vel, int dmg, double turntime) {
return PROJECTILE("youmu", plr->pos + ofs, 0,
.type = PlrProj+dmg,
.color_transform_rule = proj_clrtransform_particle,
.draw_rule = myon_proj_draw,
.rule = youmu_mirror_self_proj,
.args = {
vel*0.2*cexp(I*M_PI*0.5*sign(creal(ofs))), vel, turntime,
},
);
}
static void youmu_mirror_shot(Player *plr) {
if(!(global.frames % 4)) {
play_sound("generic_shot");
}
int p = plr->power / 100;
if(!(global.frames % 6)) {
int dmg = 105 - 10 * p;
youmu_mirror_self_shot(plr, +10 - I*20, -20.0*I, dmg, 0);
youmu_mirror_self_shot(plr, -10 - I*20, -20.0*I, dmg, 0);
}
if(!((global.frames) % 6)) {
for(int i = 0; i < p; ++i) {
int dmg = 21;
double spread = M_PI/64 * (1 + 0.5 * smoothreclamp(psin(global.frames/10.0), 0, 1, 0, 1));
youmu_mirror_self_shot(plr, (+10 + I*10), -(20.0-i)*I*cexp(-I*(1+i)*spread), dmg, 20);
youmu_mirror_self_shot(plr, (-10 + I*10), -(20.0-i)*I*cexp(+I*(1+i)*spread), dmg, 20);
}
}
}
static int youmu_split_logic(void *v, int t, double speed) {
Enemy *e = v;
TIMER(&t);
FROM_TO(30,200,1) {
tsrand_fill(2);
PARTICLE(
.texture = "smoke",
.pos = VIEWPORT_W/2 + VIEWPORT_H/2*I,
.color = rgba(0.4, 0.4, 0.4, afrand(0) * 0.2 + 0.4),
.rule = youmu_common_particle_spin,
.args = { 300 / speed, speed * 6 * cexp(I*afrand(1)*2*M_PI) },
.type = PlrProj,
);
}
FROM_TO(100,170,10) {
tsrand_fill(3);
PARTICLE(
.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 = youmu_common_particle_slice_logic,
.args = { (100 - _i) / speed },
.angle = M_PI * 2 * afrand(2),
.type = PlrProj,
);
}
FROM_TO(0, 220, 1) {
float talt = atan((t-e->args[0]/2)/30.0)*10+atan(-e->args[0]/2);
global.plr.pos = VIEWPORT_W/2.0 + (VIEWPORT_H-80)*I + VIEWPORT_W/3.0*sin(talt);
}
return 1;
}
static int youmu_split(Enemy *e, int t) {
if(t < 0)
return 1;
if(t > creal(e->args[0]))
return ACTION_DESTROY;
if(global.frames - global.plr.recovery > 0) {
return ACTION_DESTROY;
}
return player_run_bomb_logic(&global.plr, e, &e->args[3], youmu_split_logic);
}
static void youmu_mirror_bomb(Player *plr) {
play_sound("bomb_youmu_a");
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_BOMB, NULL, youmu_split, 280,0,0,0);
}
static void youmu_mirror_init(Player *plr) {
create_enemy_p(&plr->slaves, 40.0*I, ENEMY_IMMUNE, NULL, youmu_mirror_myon, 0, 0, 0, 0);
}
static void youmu_mirror_preload(void) {
const int flags = RESF_DEFAULT;
preload_resources(RES_TEXTURE, flags,
"proj/youmu",
"part/youmu_slice",
NULL);
preload_resources(RES_SFX, flags | RESF_OPTIONAL,
"bomb_youmu_a",
NULL);
}
PlayerMode plrmode_youmu_a = {
.name = "Mirror Sign",
.character = &character_youmu,
.shot_mode = PLR_SHOT_YOUMU_MIRROR,
.procs = {
.bomb = youmu_mirror_bomb,
<<<<<<< HEAD
.shot = youmu_mirror_shot,
=======
.bombbg = youmu_common_bombbg,
.shot = youmu_common_shot,
>>>>>>> redo masterspark
.init = youmu_mirror_init,
.preload = youmu_mirror_preload,
},
};

View file

@ -378,6 +378,7 @@ PlayerMode plrmode_youmu_b = {
.shot_mode = PLR_SHOT_YOUMU_HAUNTING,
.procs = {
.bomb = youmu_haunting_bomb,
.bombbg = youmu_common_bombbg,
.shot = youmu_haunting_shot,
.preload = youmu_haunting_preload,
},

View file

@ -356,20 +356,9 @@ void stage_draw_scene(StageInfo *stage) {
// disable boss background distortion
glUseProgram(0);
// fade the background during bomb
// draw bomb background
if(global.frames - global.plr.recovery < 0) {
float t = player_get_bomb_progress(&global.plr, NULL);
float fade = 1;
if(t < BOMB_RECOVERY/6)
fade = t/BOMB_RECOVERY*6;
if(t > BOMB_RECOVERY/4*3)
fade = 1-t/BOMB_RECOVERY*4 + 3;
glPushMatrix();
fade_out(fade*0.6);
glPopMatrix();
global.plr.mode->procs.bombbg(&global.plr);
}
} else if(!key_nobg) {
glClear(GL_COLOR_BUFFER_BIT);