Merge branch 'master' into stage6

This commit is contained in:
laochailan 2012-08-03 17:07:07 +02:00
commit 72d789ab5a
40 changed files with 730 additions and 29 deletions

BIN
gfx/stage1/cirnobg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 KiB

BIN
gfx/stage1/fog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
gfx/stage1/snowlayer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

BIN
gfx/stage1/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
gfx/stage2/leaves.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
gfx/stage2/road.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

BIN
gfx/stage3/border.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 KiB

BIN
gfx/stage3/spellbg1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

BIN
gfx/stage3/wspellbg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

BIN
gfx/stage3/wspellclouds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
gfx/stage3/wspellswarm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
gfx/stage4/kurumibg1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

BIN
gfx/stage4/kurumibg2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 KiB

BIN
gfx/stage4/lake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 KiB

BIN
gfx/stage4/lake.xcf Normal file

Binary file not shown.

BIN
gfx/stage4/mansion.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
gfx/stage4/mansion.xcf Normal file

Binary file not shown.

BIN
gfx/stage4/planks.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
gfx/stage4/wall.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

BIN
gfx/stage4/wall.xcf Normal file

Binary file not shown.

BIN
gfx/stage5/noise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
gfx/stage5/spell_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

BIN
gfx/stage5/spell_clouds.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

BIN
gfx/stage5/tower.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
gfx/stage5/tower.xcf Normal file

Binary file not shown.

View file

@ -27,5 +27,4 @@ void main(void) {
float f = clamp((end - z)/(end-start),0.0,1.0);
gl_FragColor = f*texture2D(tex, pos) + (1.0-f)*fog_color;
// gl_FragColor = vec4(z);
}

View file

@ -184,8 +184,7 @@ Attack *boss_add_attack(Boss *boss, AttackType type, char *name, float timeout,
boss->attacks = realloc(boss->attacks, sizeof(Attack)*(++boss->acount));
Attack *a = &boss->attacks[boss->acount-1];
// if(!boss->current)
boss->current = &boss->attacks[0];
boss->current = &boss->attacks[0];
a->type = type;
a->name = malloc(strlen(name)+1);

View file

@ -64,7 +64,6 @@ void free_attack(Attack *a);
void start_attack(Boss *b, Attack *a);
Attack *boss_add_attack(Boss *boss, AttackType type, char *name, float timeout, int hp, BossRule rule, BossRule draw_rule);
// void boss_add_waypoint(Attack *attack, complex pos, int time);
void boss_death(Boss **boss);

View file

@ -33,7 +33,7 @@ struct Enemy {
long birthtime;
int dir; // TODO: deprecate those
int dir;
int moving;
EnemyLogicRule logic_rule;

View file

@ -104,14 +104,14 @@ typedef struct {
MenuData *menu;
Dialog *dialog;
RefArray refs; // for super extra OOP-tardness: references. the cool way.
RefArray refs;
int game_over;
int points;
FPSCounter fps;
int nostagebg; // I don't want the automatic stagebg handling to mess with the config, and I don't want that longass if in more than one place either.
int nostagebg;
Replay replay;
int replaymode;
@ -137,6 +137,10 @@ void take_screenshot();
double psin();
// needed for mingw compatibility:
#undef min
#undef max
// NOTE: do NOT convert these to macros please.
// max(frand(), 0.5);
// min(huge_costly_expression, another_huge_costly_expression)

View file

@ -462,10 +462,7 @@ void draw_options_menu(MenuData *menu) {
draw_options_menu_bg(menu);
draw_text(AL_Right, 140*(1-menu->fade), 30, "Options", _fonts.mainmenu);
//glColor4f(1,1,1,0.7);
//draw_texture(SCREEN_W/2+40, SCREEN_H/2, "mainmenu/gate");
glPushMatrix();
glTranslatef(100, 100, 0);

View file

@ -138,16 +138,16 @@ void player_logic(Player* plr) {
if(plr->focus < 0 || (plr->focus > 0 && plr->focus < 30))
plr->focus++;
// if(global.frames - plr->recovery >= 0) {
switch(plr->cha) {
case Youmu:
youmu_shot(plr);
break;
case Marisa:
marisa_shot(plr);
break;
}
// }
switch(plr->cha) {
case Youmu:
youmu_shot(plr);
break;
case Marisa:
marisa_shot(plr);
break;
}
if(global.frames == plr->deathtime)
player_realdeath(plr);
@ -173,10 +173,6 @@ void player_logic(Player* plr) {
void player_bomb(Player *plr) {
if(global.frames - plr->recovery >= 0 && plr->bombs > 0) {
// Enemy *e;
// for(e = global.enemies; e; e = e->next)
// if(e->hp != ENEMY_IMMUNE)
// e->hp = 0;
delete_projectiles(&global.projs);

View file

@ -36,7 +36,6 @@ typedef struct StageInfo {
int id;
StageRule loop;
int hidden;
// reserved for draw_stage_title when/if it's used
char *title;
char *subtitle;

View file

@ -153,7 +153,6 @@ void stage2_draw() {
bgcontext.cv[1] += 0.1;
bgcontext.crot[2] += 0.5;
}
// bgcontext.cv[1] -= 0.5;
draw_stage3d(&bgcontext, 7000);

View file

@ -98,8 +98,6 @@ void stage4_lake_draw(Vector pos) {
glPushMatrix();
glTranslatef(pos[0], pos[1]+140, pos[2]);
glScalef(15,15,15);
// glRotatef(180,1,0,0);
draw_model("lake");
glPopMatrix();

142
src/stages/stage5.c Normal file
View file

@ -0,0 +1,142 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "stage5.h"
#include "stage5_events.h"
#include "stage.h"
#include "stageutils.h"
#include "global.h"
static Stage3D bgcontext;
struct {
float light_strength;
float rotshift;
float omega;
float rad;
} stagedata;
Vector **stage5_stairs_pos(Vector pos, float maxrange) {
Vector p = {0, 0, 0};
Vector r = {0, 0, 6000};
return linear3dpos(pos, maxrange, p, r);
}
void stage5_stairs_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, get_tex("stage5/tower")->gltex);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
glScalef(300,300,300);
if(!tconfig.intval[NO_SHADER]) {
Shader *sha = get_shader("tower_light");
glUseProgram(sha->prog);
glUniform3f(uniloc(sha, "lightvec"), 0, 0, 0);
glUniform4f(uniloc(sha, "color"), 0.1, 0.1, 0.5, 1);
glUniform1f(uniloc(sha, "strength"), stagedata.light_strength);
}
draw_model("tower");
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glUseProgram(0);
}
float clamp(float f, float lower, float upper) {
if(f < lower)
return lower;
if(f > upper)
return upper;
return f;
}
void stage5_draw() {
set_perspective(&bgcontext, 100, 20000);
draw_stage3d(&bgcontext, 30000);
TIMER(&global.timer);
float w = 0.005;
stagedata.rotshift += stagedata.omega;
bgcontext.crot[0] += stagedata.omega*0.5;
stagedata.rad += stagedata.omega*20;
FROM_TO(5000, 5050, 1)
stagedata.omega -= 0.005;
FROM_TO(5200, 5250, 1)
stagedata.omega += 0.005;
bgcontext.cx[0] = stagedata.rad*cos(-w*global.frames);
bgcontext.cx[1] = stagedata.rad*sin(-w*global.frames);
bgcontext.cx[2] = -1700+w*3000/M_PI*global.frames;
bgcontext.crot[2] = stagedata.rotshift-180/M_PI*w*global.frames;
stagedata.light_strength *= 0.98;
if(frand() < 0.01)
stagedata.light_strength = 5+5*frand();
}
void iku_spell_bg(Boss *b, int t) {
fill_screen(0, 300, 1, "stage5/spell_bg");
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
fill_screen(0, t*0.001, 0.7, "stage5/noise");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glTranslatef(0, -100, 0);
fill_screen(t/100.0,0,0.5,"stage5/spell_clouds");
glPushMatrix();
glTranslatef(0, 100, 0);
fill_screen(t/100.0*0.75,0,0.6,"stage5/spell_clouds");
glPushMatrix();
glTranslatef(0, 100, 0);
fill_screen(t/100.0*0.5,0,0.7,"stage5/spell_clouds");
glPushMatrix();
glTranslatef(0, 100, 0);
fill_screen(t/100.0*0.25,0,0.8,"stage5/spell_clouds");
glPopMatrix();
glPopMatrix();
glPopMatrix();
glPopMatrix();
glColor4f(1,1,1,0.05*stagedata.light_strength);
fill_screen(0, 300, 1, "stage5/spell_lightning");
glColor4f(1,1,1,1);
}
void stage5_start() {
memset(&stagedata, 0, sizeof(stagedata));
init_stage3d(&bgcontext);
add_model(&bgcontext, stage5_stairs_draw, stage5_stairs_pos);
bgcontext.crot[0] = 60;
stagedata.rotshift = 140;
stagedata.rad = 2800;
}
void stage5_end() {
free_stage3d(&bgcontext);
}
void stage5_loop() {
stage_loop(stage_get(5), stage5_start, stage5_end, stage5_draw, stage5_events, NULL, 5700);
}

13
src/stages/stage5.h Normal file
View file

@ -0,0 +1,13 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef STAGE5_H
#define STAGE5_H
void stage5_loop();
#endif

543
src/stages/stage5_events.c Normal file
View file

@ -0,0 +1,543 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include "stage5_events.h"
#include "stage5.h"
#include <global.h>
Dialog *stage5_post_mid_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", NULL);
dadd_msg(d, Left, "Hey! Stop!");
return d;
}
Dialog *stage5_boss_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", "masterspark");
dadd_msg(d, Left, "Finally!");
dadd_msg(d, Right, "Stop following me!");
dadd_msg(d, Left, "Why? You aren't involved in this, are you?");
dadd_msg(d, Right, "I don't have time for your suspicions now.");
dadd_msg(d, Left, "Sounds very suspecious, actually.");
dadd_msg(d, Right, "Ok, let's finish this quickly.");
return d;
}
Dialog *stage5_post_boss_dialog() {
Dialog *d = create_dialog(global.plr.cha == Marisa ? "dialog/marisa" : "dialog/youmu", NULL);
dadd_msg(d, Left, "I can see the top!");
dadd_msg(d, Left, "Hopefully climbing all those stairs\nwas worth it.");
return d;
}
int stage5_greeter(Enemy *e, int t) {
TIMER(&t)
AT(EVENT_DEATH) {
spawn_items(e->pos, 2,2,0,0);
return 1;
}
e->moving = 1;
e->dir = creal(e->args[0]) < 0;
if(t < 50 || t > 200)
e->pos += e->args[0];
FROM_TO(100, 180, 20) {
int i;
for(i = -(int)global.diff; i <= (int)global.diff; i++) {
create_projectile2c("bullet", e->pos, rgb(0.0,0.0,1.0), asymptotic, (3.5+(global.diff == D_Lunatic))*cexp(I*carg(global.plr.pos-e->pos) + 0.06I*i), 5);
}
}
return 1;
}
int stage5_lightburst(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 4, 1, 0, 0);
return 1;
}
if(t < 70 || t > 200)
e->pos += e->args[0];
FROM_TO(20, 170, 5) {
int i;
int c = 5+global.diff;
for(i = 0; i < c; i++) {
complex n = cexp(I*carg(global.plr.pos) + 2I*M_PI/c*i);
create_projectile2c("ball", e->pos + 50*n*cexp(-0.4I*_i*global.diff), rgb(0.3, 0, 0.7), asymptotic, 3*n, 3);
}
}
return 1;
}
int stage5_swirl(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 1, 0, 0, 0);
return 1;
}
if(t > creal(e->args[1]) && t < cimag(e->args[1]))
e->args[0] *= e->args[2];
e->pos += e->args[0];
FROM_TO(0, 400, 20-global.diff*3) {
create_projectile2c("bullet", e->pos, rgb(0.3, 0.4, 0.5), asymptotic, 2*e->args[0]*I/cabs(e->args[0]), 3);
create_projectile2c("bullet", e->pos, rgb(0.3, 0.4, 0.5), asymptotic, -2*e->args[0]*I/cabs(e->args[0]), 3);
}
return 1;
}
int stage5_limiter(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 4, 2, 0, 0);
return 1;
}
e->pos += e->args[0];
FROM_TO(0, 1200, 3) {
create_projectile2c("rice", e->pos, rgb(0.5,0.1,0.2), asymptotic, 10*cexp(I*carg(global.plr.pos-e->pos)+0.2I-0.1I*(global.diff/4)+3.0I/(_i+1)), 2);
create_projectile2c("rice", e->pos, rgb(0.5,0.1,0.2), asymptotic, 10*cexp(I*carg(global.plr.pos-e->pos)-0.2I+0.1I*(global.diff/4)-3.0I/(_i+1)), 2);
}
return 1;
}
int stage5_laserfairy(Enemy *e, int t) {
TIMER(&t)
AT(EVENT_DEATH) {
spawn_items(e->pos, 5, 5, 0, 0);
return 1;
}
FROM_TO(0, 100, 1)
e->pos += e->args[0];
if(t > 700)
e->pos -= e->args[0];
FROM_TO(100, 700, (7-global.diff)*(1+(int)creal(e->args[1]))) {
complex n = cexp(I*carg(global.plr.pos-e->pos)+(0.2-0.02*global.diff)*I*_i);
float fac = (0.5+0.2*global.diff);
create_lasercurve2c(e->pos, 100, 300, rgb(0.7, 0.3, 1), las_accel, fac*4*n, fac*0.05*n);
create_projectile2c("plainball", e->pos, rgb(0.7, 0.3, 1), accelerated, fac*4*n, fac*0.05*n)->draw = ProjDrawAdd;
}
return 1;
}
int stage5_miner(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 2, 0, 0, 0);
return 1;
}
e->pos += e->args[0];
FROM_TO(0, 600, 5-global.diff/2) {
create_projectile1c("rice", e->pos + 20*cexp(2I*M_PI*frand()), rgb(0,0,cabs(e->args[0])), linear, cexp(2I*M_PI*frand()));
}
return 1;
}
int stage5_explosion(Enemy *e, int t) {
TIMER(&t)
AT(EVENT_DEATH) {
spawn_items(e->pos, 5, 5, 0, creal(e->args[1]));
return 1;
}
FROM_TO(0, 80, 1)
e->pos += e->args[0];
FROM_TO(90, 300, 7-global.diff)
create_projectile2c("soul", e->pos, rgb(0,0,1), asymptotic, 4*cexp(0.5I*_i), 3)->draw = ProjDrawAdd;
FROM_TO(200, 720, 6-global.diff) {
create_projectile2c("rice", e->pos, rgb(1,0,0), asymptotic, 2*cexp(-0.3I*_i+frand()*I), 3);
create_projectile2c("rice", e->pos, rgb(1,0,0), asymptotic, -2*cexp(-0.3I*_i+frand()*I), 3);
}
FROM_TO(500, 800, 80-5*global.diff)
create_laserline(e->pos, 10*cexp(I*carg(global.plr.pos-e->pos)+0.04I*(1-2*frand())), 60, 120, rgb(1, 0.3, 1));
return 1;
}
void iku_mid_intro(Boss *b, int t) {
TIMER(&t);
b->pos += -1-7I+10*t*(cimag(b->pos)<-200);
FROM_TO(90, 110, 10) {
create_enemy2c(b->pos, ENEMY_IMMUNE, Swirl, stage5_explosion, -2-0.5*_i+I*_i, _i == 1);
}
AT(960)
killall(global.enemies);
}
Boss *create_iku_mid() {
Boss *b = create_boss("Bombs?", "iku", VIEWPORT_W+800I);
boss_add_attack(b, AT_SurvivalSpell, "Static Bombs", 16, 10, iku_mid_intro, NULL);
return b;
}
int stage5_lightburst2(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 4, 3, 0, 0);
return 1;
}
if(t < 70 || t > 200)
e->pos += e->args[0];
FROM_TO(20, 170, 5) {
int i;
int c = 5+global.diff;
for(i = 0; i < c; i++) {
complex n = cexp(I*carg(global.plr.pos-e->pos) + 2I*M_PI/c*i);
create_projectile2c("bigball", e->pos + 50*n*cexp(-1I*_i*global.diff), rgb(0.3, 0, 0.7+0.3*(_i&1)), asymptotic, 2.5*n+0.25*global.diff*frand()*cexp(2I*M_PI*frand()), 3);
}
}
return 1;
}
int stage5_superbullet(Enemy *e, int t) {
TIMER(&t);
AT(EVENT_DEATH) {
spawn_items(e->pos, 4, 3, 0, 0);
return 1;
}
FROM_TO(0, 70, 1)
e->pos += e->args[0];
FROM_TO(60, 200, 1) {
complex n = cexp(I*M_PI*sin(_i/(8.0+global.diff)+frand()*0.1)+I*carg(global.plr.pos-e->pos));
create_projectile2c("bullet", e->pos + 50*n, rgb(0.6, 0, 0), asymptotic, 2*n, 10);
}
FROM_TO(260, 400, 1)
e->pos -= e->args[0];
return 1;
}
void iku_intro(Boss *b, int t) {
GO_TO(b, VIEWPORT_W/2+300I, 0.01);
if(t == 100)
global.dialog = stage5_boss_dialog();
}
void iku_bolts(Boss *b, int time) {
int t = time % 400;
TIMER(&t);
FROM_TO(0, 400, 2)
create_projectile2c("bigball", VIEWPORT_W*frand()-15I, rgb(1,0,0), accelerated, 1-2*frand()+1.7I, -0.01I)->draw = ProjDrawSub;
FROM_TO(60, 400, 50) {
int i, c = 10+global.diff;
for(i = 0; i < c; i++) {
create_projectile2c("ball", b->pos, rgb(0.4, 1, 1), asymptotic, (i+2)*0.4*cexp(I*carg(global.plr.pos-b->pos))+0.2*(global.diff-1)*frand(), 3)->draw = ProjDrawAdd;
}
}
FROM_TO(0, 70, 1)
GO_TO(b, 100+300I, 0.02);
FROM_TO(100, 200, 1)
GO_TO(b, VIEWPORT_W/2+100I, 0.02);
FROM_TO(230, 300, 1)
GO_TO(b, VIEWPORT_W-100+300I, 0.02);
FROM_TO(330, 400, 1)
GO_TO(b, VIEWPORT_W/2+100I, 0.02);
}
void iku_atmospheric(Boss *b, int time) {
if(time < 0) {
GO_TO(b, VIEWPORT_W/2+200I, 0.06);
return;
}
int t = time % 500;
TIMER(&t);
FROM_TO(0, 500, 23-2*global.diff) {
complex p1 = VIEWPORT_W*frand() + VIEWPORT_H/2*I*frand();
complex p2 = p1 + (120+20*global.diff)*cexp(0.5I-frand()*I)*(1-2*(frand() > 0.5));
int i;
int c = 10;
for(i = -c*0.5; i <= c*0.5; i++) {
create_projectile2c("ball", p1+(p2-p1)/c*i, rgb(1/(1+fabs(0.3*i)), 1, 1), accelerated, 0, (0.005+0.001*global.diff)*cexp(I*carg(p2-p1)+I*M_PI/2+0.2I*i))->draw = ProjDrawAdd;
}
}
FROM_TO(0, 500, 7-global.diff)
create_projectile2c("thickrice", VIEWPORT_W*frand(), rgb(0,0.3,0.7), accelerated, 0, 0.01I);
}
complex bolts2_laser(Laser *l, float t) {
return creal(l->args[0])+I*cimag(l->pos) + copysign(1,cimag(l->args[0]-l->pos))*0.06I*t*t + (20+4*global.diff)*sin(t*0.1+creal(l->args[0]));
}
void iku_bolts2(Boss *b, int time) {
int t = time % 400;
TIMER(&t);
FROM_TO(0, 400, 2)
create_projectile2c("bigball", VIEWPORT_W*frand()-15I, rgb(1,0,0), accelerated, 1-2*frand()+1.7I, -0.01I)->draw = ProjDrawSub;
FROM_TO(0, 400, 60)
create_lasercurve1c(creal(global.plr.pos), 100, 200, rgb(0.3,1,1), bolts2_laser, global.plr.pos);
FROM_TO(0, 400, 5-global.diff)
if(frand() < 0.9)
create_projectile1c("plainball", b->pos, rgb(0.2,0,0.8), linear, cexp(0.1I*_i));
FROM_TO(0, 70, 1)
GO_TO(b, 100+200I, 0.02);
FROM_TO(230, 300, 1)
GO_TO(b, VIEWPORT_W-100+200I, 0.02);
}
int lightning_slave(Enemy *e, int t) {
if(t < 0)
return 1;
if(t > 200)
return ACTION_DESTROY;
TIMER(&t);
e->pos += e->args[0];
FROM_TO(0,200,20)
e->args[0] *= cexp(2I*M_PI*frand());
FROM_TO(0, 200, 3)
if(cabs(e->pos-global.plr.pos) > 60)
create_projectile2c("wave", e->pos, rgb(0, 1, 1), accelerated, 0.5*e->args[0]/cabs(e->args[0])*I, 0.005*(1-2*frand()+I*frand()))->draw = ProjDrawAdd;
return 1;
}
void iku_lightning(Boss *b, int time) {
int t = time % 151;
if(time == EVENT_DEATH) {
killall(global.enemies);
return;
}
if(time < 0) {
GO_TO(b, VIEWPORT_W/2.0+200I, 0.03);
return;
}
TIMER(&t);
FROM_TO(0, 100, 1) {
complex n = cexp(2I*M_PI*frand());
float l = 200*frand()+100;
float s = 4+_i*0.01;
create_particle2c("flare", b->pos+l*n, rgb(0.7,1,1), Shrink, timeout_linear, l/s, -s*n);
}
AT(150) {
int i;
for(i = 0; i < global.diff+1; i++)
create_enemy1c(b->pos, ENEMY_IMMUNE, NULL, lightning_slave, 10*cexp(I*carg(global.plr.pos - b->pos)+2I*M_PI/(global.diff+1)*i));
}
}
void iku_bolts3(Boss *b, int time) {
int t = time % 400;
TIMER(&t);
FROM_TO(0, 400, 2)
create_projectile2c("bigball", VIEWPORT_W*frand()-15I, rgb(1,0,0), accelerated, 1-2*frand()+1.8I, -0.01I)->draw = ProjDrawSub;
FROM_TO(60, 400, 60) {
int i, c = 10+global.diff;
complex n = cexp(I*carg(global.plr.pos-b->pos)+0.1I-0.2I*frand());
for(i = 0; i < c; i++) {
create_projectile2c("ball", b->pos, rgb(0.4, 1, 1), asymptotic, (i+2)*0.4*n+0.2*(global.diff-1)*frand(), 3)->draw = ProjDrawAdd;
}
}
FROM_TO(0, 400, 5-global.diff)
if(frand() < 0.9)
create_projectile1c("plainball", b->pos, rgb(0.2,0,0.8), linear, cexp(0.1I*_i));
FROM_TO(0, 70, 1)
GO_TO(b, 100+200I, 0.02);
FROM_TO(230, 300, 1)
GO_TO(b, VIEWPORT_W-100+200I, 0.02);
}
int induction_bullet(Projectile *p, int t) {
if(t < 0)
return 1;
p->pos = p->pos0 + p->args[0]*t*cexp(p->args[1]*t);
p->angle = carg(p->args[0]*cexp(p->args[1]*t)*(1+p->args[1]*t));
return 1;
}
complex cathode_laser(Laser *l, float t) {
return l->pos + l->args[0]*t*cexp(l->args[1]*t);
}
void iku_cathode(Boss *b, int t) {
if(t < 0) {
GO_TO(b, VIEWPORT_W/2+200I, 0.02);
return;
}
TIMER(&t)
FROM_TO(50, 1800, 70-global.diff*10) {
int i;
int c = 5+global.diff;
for(i = 0; i < c; i++) {
create_projectile2c("bigball", b->pos, rgb(0.2, 0.4, 1), induction_bullet, 2*cexp(2I*M_PI*frand()), 0.01*I*(1-2*(_i&1)))->draw = ProjDrawAdd;
create_lasercurve2c(b->pos, 60, 200, rgb(0.4, 1, 1), cathode_laser, 2*cexp(2I*M_PI*M_PI*frand()), 0.015*I*(1-2*(_i&1)));
}
}
}
void iku_induction(Boss *b, int t) {
if(t < 0) {
GO_TO(b, VIEWPORT_W/2+200I, 0.02);
return;
}
TIMER(&t);
FROM_TO(0, 1800, 8) {
int i,j;
int c = 5+global.diff;
for(i = 0; i < c; i++) {
for(j = 0; j < 2; j++)
create_projectile2c("ball", b->pos, rgb(0, 1, 1), induction_bullet, 2*cexp(2I*M_PI/c*i+I*M_PI/2+0.6I*(_i/6)), (0.01+0.001*global.diff)*I*(1-2*j))->draw = ProjDrawAdd;
}
}
}
void iku_spell_bg(Boss *b, int t);
Boss *create_iku() {
Boss *b = create_boss("Nagae Iku", "iku", VIEWPORT_W/2-200I);
boss_add_attack(b, AT_Move, "Introduction", 3, 0, iku_intro, NULL);
boss_add_attack(b, AT_Normal, "Bolts1", 20, 20000, iku_bolts, NULL);
boss_add_attack(b, AT_Spellcard, "High Voltage ~ Atmospheric Discharge", 30, 30000, iku_atmospheric, iku_spell_bg);
boss_add_attack(b, AT_Normal, "Bolts2", 25, 20000, iku_bolts2, NULL);
boss_add_attack(b, AT_Spellcard, "Charge Sign ~ Artificial Lightning", 30, 35000, iku_lightning, iku_spell_bg);
boss_add_attack(b, AT_Normal, "Bolts3", 20, 20000, iku_bolts3, NULL);
boss_add_attack(b, AT_Spellcard, "Spark Sign ~ Natural Cathode", 30, 35000, iku_cathode, iku_spell_bg);
boss_add_attack(b, AT_Spellcard, "Current Sign ~ Induction", 30, 35000, iku_induction, iku_spell_bg);
return b;
}
void stage5_events() {
TIMER(&global.timer);
FROM_TO(60, 120, 10)
create_enemy1c(VIEWPORT_W+70I+50*_i*I, 300, Fairy, stage5_greeter, -3);
FROM_TO(270, 320, 25)
create_enemy1c(VIEWPORT_W/4+VIEWPORT_W/2*_i, 2000, BigFairy, stage5_lightburst, 2I);
FROM_TO(500, 600, 10)
create_enemy3c(200I*frand(), 500, Swirl, stage5_swirl, 4+I, 70+20*frand()+200I, cexp(-0.05I));
FROM_TO(700, 800, 10)
create_enemy3c(VIEWPORT_W+200I*frand(), 500, Swirl, stage5_swirl, -4+frand()*I, 70+20*frand()+200I, cexp(0.05I));
FROM_TO(870, 1000, 50)
create_enemy1c(VIEWPORT_W/4+VIEWPORT_W/2*(_i&1), 2000, BigFairy, stage5_limiter, I);
AT(1000)
create_enemy1c(VIEWPORT_W/2, 9000, BigFairy, stage5_laserfairy, 2I);
FROM_TO(1900, 2200, 40)
create_enemy1c(VIEWPORT_W+200I*frand(), 500, Swirl, stage5_miner, -3+2I*frand());
FROM_TO(1500, 2400, 80)
create_enemy1c(VIEWPORT_W*(_i&1)+100I, 300, Fairy, stage5_greeter, 3-6*(_i&1));
FROM_TO(2200, 2600, 40)
create_enemy1c(VIEWPORT_W/10*_i, 200, Swirl, stage5_miner, 3I);
AT(2900)
global.boss = create_iku_mid();
AT(2920)
global.dialog = stage5_post_mid_dialog();
FROM_TO(3000, 3200, 100)
create_enemy1c(VIEWPORT_W/2 + VIEWPORT_W/6*(1-2*(_i&1)), 2000, BigFairy, stage5_lightburst2, -1+2*(_i&1) + 2I);
FROM_TO(3300, 4000, 50)
create_enemy1c(200I+VIEWPORT_W*(_i&1), 1500, Fairy, stage5_superbullet, 3-6*(_i&1));
AT(3400) {
create_enemy2c(VIEWPORT_W/4, 6000, BigFairy, stage5_laserfairy, 2I, 1);
create_enemy2c(VIEWPORT_W/4*3, 6000, BigFairy, stage5_laserfairy, 2I, 1);
}
FROM_TO(4200, 5000, 20) {
float f = frand();
create_enemy3c(VIEWPORT_W/2, 400, Swirl, stage5_swirl, 2*cexp(I*M_PI*f)+I, 60 + 100I, cexp(0.01I*(1-2*(f<0.5))));
}
AT(5300)
global.boss = create_iku();
AT(5320)
global.dialog = stage5_post_boss_dialog();
}

View file

@ -0,0 +1,13 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef STAGE5_EVENTS_H
#define STAGE5_EVENTS_H
void stage5_events();
#endif