diff --git a/CMakeLists.txt b/CMakeLists.txt
index c1391b59..8deb5cad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,10 @@ else()
set(DATA_DIR "share/taisei")
endif()
-install(DIRECTORY gfx DESTINATION ${DATA_DIR})
+install(DIRECTORY gfx DESTINATION ${DATA_DIR}
+ FILES_MATCHING PATTERN "*.png")
+install(DIRECTORY gfx DESTINATION ${DATA_DIR}
+ FILES_MATCHING PATTERN "*.ttf")
install(DIRECTORY sfx DESTINATION ${DATA_DIR})
install(DIRECTORY shader DESTINATION ${DATA_DIR})
diff --git a/gfx/fairy_circle.png b/gfx/fairy_circle.png
index a9c3401a..93c28479 100644
Binary files a/gfx/fairy_circle.png and b/gfx/fairy_circle.png differ
diff --git a/gfx/fairy_circle.svg b/gfx/fairy_circle.svg
index a1db9dff..032fe2c5 100644
--- a/gfx/fairy_circle.svg
+++ b/gfx/fairy_circle.svg
@@ -10,17 +10,28 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="354.45395"
- height="354.45395"
+ width="368.32498"
+ height="368.32498"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
sodipodi:docname="fairy_circle.svg"
inkscape:export-filename="/home/laochailan/src/taisei/gfx/fairy_circle.png"
- inkscape:export-xdpi="15.234701"
- inkscape:export-ydpi="15.234701">
+ inkscape:export-xdpi="15.638364"
+ inkscape:export-ydpi="15.638364">
+
+
+
+
@@ -33,199 +44,10 @@
offset="1"
id="stop3838" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ id="filter3807"
+ color-interpolation-filters="sRGB">
+ id="filter3811"
+ color-interpolation-filters="sRGB">
+ id="filter3815"
+ color-interpolation-filters="sRGB">
+ r="182.26353" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ inkscape:window-y="-2"
+ inkscape:window-maximized="1"
+ inkscape:snap-global="false" />
@@ -308,21 +312,33 @@
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(-23.288305,-119.5411)">
+ transform="translate(-16.352778,-112.60557)">
+
+ id="g3992"
+ style="filter:url(#filter4118)">
+
+
+
+
+
+
diff --git a/gfx/items/bomb.png b/gfx/items/bomb.png
index 28b1e94f..ddcc5e93 100644
Binary files a/gfx/items/bomb.png and b/gfx/items/bomb.png differ
diff --git a/gfx/items/bomb.svg b/gfx/items/bomb.svg
index 148de534..4949afb4 100644
--- a/gfx/items/bomb.svg
+++ b/gfx/items/bomb.svg
@@ -17,8 +17,8 @@
inkscape:version="0.48.1 r9760"
sodipodi:docname="bomb.svg"
inkscape:export-filename="/home/laochailan/src/taisei/gfx/items/bomb.png"
- inkscape:export-xdpi="12.392977"
- inkscape:export-ydpi="12.392977">
+ inkscape:export-xdpi="7.75"
+ inkscape:export-ydpi="7.75">
+ inkscape:export-xdpi="7.7456102"
+ inkscape:export-ydpi="7.7456102">
+
+
+
diff --git a/gfx/proj/crystal.png b/gfx/proj/crystal.png
new file mode 100644
index 00000000..5f544a82
Binary files /dev/null and b/gfx/proj/crystal.png differ
diff --git a/gfx/proj/crystal.svg b/gfx/proj/crystal.svg
new file mode 100644
index 00000000..b862fdf4
--- /dev/null
+++ b/gfx/proj/crystal.svg
@@ -0,0 +1,137 @@
+
+
+
+
diff --git a/gfx/proj/flea.png b/gfx/proj/flea.png
new file mode 100644
index 00000000..0cffb9d9
Binary files /dev/null and b/gfx/proj/flea.png differ
diff --git a/gfx/proj/flea.svg b/gfx/proj/flea.svg
new file mode 100644
index 00000000..6438c79b
--- /dev/null
+++ b/gfx/proj/flea.svg
@@ -0,0 +1,130 @@
+
+
+
+
diff --git a/gfx/proj/marisa.png b/gfx/proj/marisa.png
index 357c2de2..f4507704 100644
Binary files a/gfx/proj/marisa.png and b/gfx/proj/marisa.png differ
diff --git a/gfx/proj/marisa.svg b/gfx/proj/marisa.svg
index 800a597e..ecb8b257 100644
--- a/gfx/proj/marisa.svg
+++ b/gfx/proj/marisa.svg
@@ -17,8 +17,8 @@
inkscape:version="0.48.1 r9760"
sodipodi:docname="marisa.svg"
inkscape:export-filename="/home/laochailan/src/taisei/gfx/proj/marisa.png"
- inkscape:export-xdpi="101.66402"
- inkscape:export-ydpi="101.66402">
+ inkscape:export-xdpi="104.20562"
+ inkscape:export-ydpi="104.20562">
+
+
+
+
+
+
-
-
-
+
+
+
+
diff --git a/gfx/proj/thickrice.png b/gfx/proj/thickrice.png
new file mode 100644
index 00000000..93fcbcf3
Binary files /dev/null and b/gfx/proj/thickrice.png differ
diff --git a/gfx/proj/thickrice.svg b/gfx/proj/thickrice.svg
new file mode 100644
index 00000000..d1028949
--- /dev/null
+++ b/gfx/proj/thickrice.svg
@@ -0,0 +1,101 @@
+
+
+
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2431d7df..935e49f6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,8 +7,14 @@ find_package(ALUT REQUIRED)
find_package(PNG REQUIRED)
find_package(SDL_ttf REQUIRED)
find_package(GLEW REQUIRED)
-find_package(BISON)
-find_package(FLEX)
+find_package(BISON REQUIRED)
+find_package(FLEX REQUIRED)
+find_package(Freetype)
+find_package(ZLIB)
+
+if(WIN32)
+ add_definitions(-lwinmm -ldxguid -limm32 -lversion)
+endif()
BISON_TARGET(cfgparser config.y ${CMAKE_CURRENT_SOURCE_DIR}/parser.c)
FLEX_TARGET(cfgscanner config.l ${CMAKE_CURRENT_SOURCE_DIR}/lexer.c)
@@ -51,12 +57,27 @@ endif()
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
-include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+set(LIBs ${LIBs}
+ ${SDL_LIBRARY}
+ ${PNG_LIBRARY}
+ ${SDLTTF_LIBRARY}
+ ${OPENAL_LIBRARY}
+ ${ALUT_LIBRARY}
+ ${GLEW_LIBRARY}
+ ${OPENGL_LIBRARY})
+
-include_directories(${SDL_INCLUDE_DIR} ${ALUT_INCLUDE_DIR} ${GLEW_INCLUDE_PATH})
+if(FREETYPE_FOUND)
+ set(LIBs ${LIBs} ${FREETYPE_LIBRARY})
+endif()
+
+if(ZLIB_FOUND)
+ set(LIBs ${LIBs} ${ZLIB_LIBRARY})
+endif()
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${SDL_INCLUDE_DIR} ${ALUT_INCLUDE_DIR} ${GLEW_INCLUDE_PATH})
add_executable(taisei WIN32 ${SRCs})
-target_link_libraries(taisei ${SDL_LIBRARY} ${PNG_LIBRARY} ${SDLTTF_LIBRARY}
- ${OPENAL_LIBRARY} ${ALUT_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARY})
+target_link_libraries(taisei ${LIBs})
if(RELATIVE)
install(TARGETS taisei RUNTIME DESTINATION .)
diff --git a/src/enemy.c b/src/enemy.c
index 114370b4..a0e0ae8b 100644
--- a/src/enemy.c
+++ b/src/enemy.c
@@ -37,8 +37,17 @@ void create_enemy_p(Enemy **enemies, complex pos, int hp, EnemyDrawRule draw_rul
}
void _delete_enemy(void **enemies, void* enemy) {
- if(((Enemy* )enemy)->hp <= 0)
- ((Enemy* )enemy)->logic_rule(enemy, EVENT_DEATH);
+ Enemy *e = (Enemy *)enemy;
+
+ if(e->hp <= 0) {
+ int i;
+ for(i = 0; i < 10; i++)
+ create_particle2c("flare", e->pos, NULL, Fade, timeout_linear, 10, (3+frand()*10)*cexp(I*frand()*2*M_PI));
+ create_particle1c("blast", e->pos, NULL, Blast, timeout, 20);
+ create_particle1c("blast", e->pos, NULL, Blast, timeout, 20);
+ create_particle2c("blast", e->pos, NULL, GrowFade, timeout, 15,0);
+ e->logic_rule(enemy, EVENT_DEATH);
+ }
del_ref(enemy);
delete_element((void **)enemies, enemy);
@@ -69,7 +78,7 @@ void Fairy(Enemy *e, int t) {
glPushMatrix();
glRotatef(global.frames*10,0,0,1);
glScalef(s, s, s);
- glColor3f(0.2,0.7,1);
+// glColor4f(1,1,1,0.7);
draw_texture(0,0,"fairy_circle");
glPopMatrix();
@@ -103,7 +112,10 @@ void process_enemies(Enemy **enemies) {
while(enemy != NULL) {
enemy->logic_rule(enemy, global.frames - enemy->birthtime);
-
+
+ if(enemy->hp != ENEMY_IMMUNE && cabs(enemy->pos - global.plr.pos) < 25)
+ plr_death(&global.plr);
+
if(enemy->hp != ENEMY_IMMUNE
&& (creal(enemy->pos) < -20 || creal(enemy->pos) > VIEWPORT_W + 20
|| cimag(enemy->pos) < -20 || cimag(enemy->pos) > VIEWPORT_H + 20
@@ -113,6 +125,6 @@ void process_enemies(Enemy **enemies) {
delete_enemy(enemies, del);
} else {
enemy = enemy->next;
- }
+ }
}
}
\ No newline at end of file
diff --git a/src/global.c b/src/global.c
index 3ac710b8..de0be6f0 100644
--- a/src/global.c
+++ b/src/global.c
@@ -56,4 +56,8 @@ void set_ortho() {
glOrtho(0, SCREEN_W, SCREEN_H, 0, -100, 100);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
+}
+
+inline double frand() {
+ return rand()/(double)RAND_MAX;
}
\ No newline at end of file
diff --git a/src/global.h b/src/global.h
index d38dba80..a56708fb 100644
--- a/src/global.h
+++ b/src/global.h
@@ -121,4 +121,6 @@ void frame_rate();
void calc_fps(FPSCounter *fps);
void set_ortho();
+double frand();
+
#endif
\ No newline at end of file
diff --git a/src/item.c b/src/item.c
index 2b769640..58838559 100644
--- a/src/item.c
+++ b/src/item.c
@@ -74,8 +74,13 @@ void move_item(Item *i) {
void process_items() {
Item *item = global.items, *del = NULL;
int v;
+
+ float r = 30;
+ if(global.plr.focus > 0);
+ r *= 2;
+
while(item != NULL) {
- if(cimag(global.plr.pos) < POINT_OF_COLLECT || cabs(global.plr.pos - item->pos) < 19 + global.plr.focus
+ if(cimag(global.plr.pos) < POINT_OF_COLLECT || cabs(global.plr.pos - item->pos) < r
|| global.frames - global.plr.recovery < 0)
item->auto_collect = 1;
@@ -115,12 +120,27 @@ void process_items() {
}
int collision_item(Item *i) {
- if(cabs(global.plr.pos - i->pos) < 5)
+ if(cabs(global.plr.pos - i->pos) < 10)
return 1;
return 0;
}
-void spawn_item(complex pos, Type type) {
- create_item(pos, 5*cexp(I*rand()/(float)RAND_MAX*M_PI*2), type);
+inline void spawn_item(complex pos, Type type) {
+ create_item(pos, 5*cexp(I*rand()/frand()*M_PI*2), type);
+}
+
+void spawn_items(complex pos, int point, int power, int bomb, int life) {
+ int i;
+ for(i = 0; i < point; i++)
+ spawn_item(pos, Point);
+
+ for(i = 0; i < power; i++)
+ spawn_item(pos, Power);
+
+ for(i = 0; i < bomb; i++)
+ spawn_item(pos, Bomb);
+
+ for(i = 0; i < life; i++)
+ spawn_item(pos, Life);
}
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index b4dc752f..f44c48a7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,7 +28,7 @@ void init_gl() {
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glViewport(0, 0, SCREEN_W, SCREEN_H);
-
+
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
@@ -39,10 +39,15 @@ void init_gl() {
void shutdown() {
delete_textures();
delete_animations();
- delete_sounds();
- delete_shaders();
- alutExit();
+ if(!tconfig.intval[NO_SHADER])
+ delete_shaders();
+
+ if(!tconfig.intval[NO_AUDIO]) {
+ delete_sounds();
+ alutExit();
+ }
+
SDL_FreeSurface(display);
SDL_Quit();
}
diff --git a/src/menu/charselect.c b/src/menu/charselect.c
index 72e4aa8d..5bc3a09f 100644
--- a/src/menu/charselect.c
+++ b/src/menu/charselect.c
@@ -90,6 +90,24 @@ void draw_char_menu(MenuData *menu, MenuData *mod) {
glPopMatrix();
}
+ glColor4f(1,1,1,0.3*sin(menu->frames/20.0)+0.5);
+
+ for(i = 0; i <= 1; i++) {
+ glPushMatrix();
+
+ glTranslatef(60 + (SCREEN_W/2 - 30)*i, SCREEN_H/2+80, 0);
+ glScalef(1-2*i,1,1);
+ if(i) glCullFace(GL_FRONT);
+ glBegin(GL_TRIANGLES);
+ glVertex3f(0,0,0);
+ glVertex3f(20,30,0);
+ glVertex3f(20,-30,0);
+ glEnd();
+
+ glPopMatrix();
+ }
+
+ glCullFace(GL_BACK);
glColor4f(1,1,1,1);
fade_out(menu->fade);
diff --git a/src/menu/ingamemenu.c b/src/menu/ingamemenu.c
index 0a25e844..01a4cece 100644
--- a/src/menu/ingamemenu.c
+++ b/src/menu/ingamemenu.c
@@ -68,7 +68,7 @@ void draw_ingame_menu(MenuData *menu) {
glPopMatrix();
// cirno's perfect math class #2: Euler Sign ~ Differential Fun
- menu->drawdata[0] += (menu->cursor*35 - menu->drawdata[0])/10.0;
+ menu->drawdata[0] += (menu->cursor*35 - menu->drawdata[0])/7.0;
menu->drawdata[1] += (strlen(menu->entries[menu->cursor].name)*5 - menu->drawdata[1])/10.0;
int i;
diff --git a/src/player.c b/src/player.c
index 4598a8ab..1e38bf6b 100644
--- a/src/player.c
+++ b/src/player.c
@@ -57,8 +57,8 @@ void player_draw(Player* plr) {
glScalef(-1,1,1);
}
- if(global.frames - abs(plr->recovery) < 0 && (global.frames/17)&1)
- glColor4f(0.8,0.8,1,0.9);
+ if(global.frames - abs(plr->recovery) < 0 && (global.frames/8)&1)
+ glColor4f(0.4,0.4,1,0.9);
draw_animation_p(0, 0, !plr->moving, plr->ani);
@@ -96,9 +96,6 @@ void player_logic(Player* plr) {
break;
}
- if(plr->deathtime > 0)
- create_particle2c("flare", plr->pos, rgb(255,0,0), Shrink, timeout_linear, 10, 4*cexp(I*rand()));
-
if(global.frames == plr->deathtime)
plr_realdeath(plr);
}
@@ -136,7 +133,7 @@ void plr_realdeath(Player *plr) {
create_item(plr->pos, -6-15*I, Power);
plr->pos = VIEWPORT_W/2 + VIEWPORT_H*I;
- plr->recovery = -(global.frames + 200);
+ plr->recovery = -(global.frames + 150);
if(global.plr.bombs < 3)
global.plr.bombs = 3;
@@ -147,5 +144,11 @@ void plr_realdeath(Player *plr) {
}
void plr_death(Player *plr) {
- plr->deathtime = global.frames + DEATHBOMB_TIME;
+ if(plr->deathtime == -1) {
+ int i;
+ for(i = 0; i < 20; i++)
+ create_particle2c("flare", plr->pos, NULL, Shrink, timeout_linear, 40, (3+frand()*7)*cexp(I*rand()));
+ create_particle2c("blast", plr->pos, rgb(1,0.5,0.3), GrowFade, timeout, 35, 2.4);
+ plr->deathtime = global.frames + DEATHBOMB_TIME;
+ }
}
\ No newline at end of file
diff --git a/src/plrmodes.c b/src/plrmodes.c
index 144534c7..5daa0ccd 100644
--- a/src/plrmodes.c
+++ b/src/plrmodes.c
@@ -93,6 +93,17 @@ int youmu_homing(Projectile *p, int t) { // a[0]: velocity, a[1]: target, a[2]:
/* Marisa */
+void MariLaser(Projectile *p, int t) {
+ Player *plr = (Player *)REF(p->args[1]);
+ if(cimag(p->pos) - cimag(plr->pos) < 90) {
+ glScissor(VIEWPORT_X, SCREEN_H - cimag(plr->pos)+5, VIEWPORT_W+VIEWPORT_X, VIEWPORT_H);
+ glEnable(GL_SCISSOR_TEST);
+ }
+ ProjDraw(p, t);
+
+ glDisable(GL_SCISSOR_TEST);
+}
+
int mari_laser(Projectile *p, int t) {
linear(p, t);
@@ -106,8 +117,8 @@ int mari_laser(Projectile *p, int t) {
void marisa_shot(Player *plr) {
if(plr->fire) {
if(!(global.frames % 4)) {
- create_projectile2c("marisa", +10, NULL, mari_laser, -20I, add_ref(plr))->type = PlrProj;
- create_projectile2c("marisa", -10, NULL, mari_laser, -20I, add_ref(plr))->type = PlrProj;
+ create_projectile_p(&global.projs, get_tex("proj/marisa"), +15, NULL, MariLaser, mari_laser, -20I, add_ref(plr),0,0)->type = PlrProj;
+ create_projectile_p(&global.projs, get_tex("proj/marisa"), -15, NULL, MariLaser, mari_laser, -20I, add_ref(plr),0,0)->type = PlrProj;
}
}
}
\ No newline at end of file
diff --git a/src/projectile.c b/src/projectile.c
index 70485c4b..2d16b89b 100644
--- a/src/projectile.c
+++ b/src/projectile.c
@@ -84,7 +84,7 @@ void delete_projectiles(Projectile **projs) {
int collision_projectile(Projectile *p) {
if(p->type == FairyProj) {
- float angle = carg(global.plr.pos - p->pos);
+ float angle = carg(global.plr.pos - p->pos) + p->angle;
int projr = sqrt(pow(p->tex->w/4*cos(angle),2)*8/10 + pow(p->tex->h/2*sin(angle)*8/10,2));
if(cabs(global.plr.pos - p->pos) < projr + 1)
@@ -174,6 +174,15 @@ int accelerated(Projectile *p, int t) {
return 1;
}
+int asymptotic(Projectile *p, int t) { // v = a[0]*(a[1] + 1); a[1] -> 0
+ p->angle = carg(p->args[0] + p->args[1]);
+
+ p->args[1] *= 0.8;
+ p->pos += p->args[0]*(p->args[1] + 1);
+
+ return 1;
+}
+
void _ProjDraw(Projectile *proj, int t) {
if(proj->clr != NULL && !tconfig.intval[NO_SHADER]) {
GLuint shader = get_shader("bullet_color");
@@ -202,6 +211,23 @@ void ProjDraw(Projectile *proj, int t) {
glPopMatrix();
}
+void Blast(Projectile *p, int t) {
+ if(t == 1) {
+ p->args[1] = frand()*360 + frand()*I;
+ p->args[2] = frand() + frand()*I;
+ }
+
+ 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]));
+ glScalef(t/p->args[0], t/p->args[0], 1);
+ glColor4f(0.3,0.6,1,1 - t/p->args[0]);
+ draw_texture_p(0,0,p->tex);
+ glPopMatrix();
+
+ glColor4f(1,1,1,1);
+}
+
void Shrink(Projectile *p, int t) {
glPushMatrix();
float s = 2.0-t/p->args[0]*2;
@@ -224,12 +250,28 @@ void DeathShrink(Projectile *p, int t) {
glPopMatrix();
}
+void GrowFade(Projectile *p, int t) {
+ glPushMatrix();
+ glTranslatef(creal(p->pos), cimag(p->pos), 0);
+ glRotatef(p->angle*180/M_PI+90, 0, 0, 1);
+ glScalef(t/p->args[0]*(1+p->args[1]), t/p->args[0]*(1+p->args[1]), 1);
+
+ if(p->clr)
+ glColor4f(p->clr->r,p->clr->g,p->clr->b,1-t/p->args[0]);
+ else
+ glColor4f(1,1,1,1-t/p->args[0]);
+
+ draw_texture_p(0,0,p->tex);
+
+ glColor4f(1,1,1,1);
+ glPopMatrix();
+}
+
int bullet_flare_move(Projectile *p, int t) {
if(t > 16 || REF(p->args[1]) == NULL) {
free_ref(p->args[1]);
return ACTION_DESTROY;
- }
-
+ }
p->pos = ((Projectile *) REF(p->args[1]))->pos;
p->angle = ((Projectile *) REF(p->args[1]))->angle;
diff --git a/src/projectile.h b/src/projectile.h
index 4d8f5e99..901c5f30 100644
--- a/src/projectile.h
+++ b/src/projectile.h
@@ -72,9 +72,13 @@ Projectile *get_proj(Projectile *hay, int birthtime);
int linear(Projectile *p, int t);
int accelerated(Projectile *p, int t);
+int asymptotic(Projectile *p, int t);
void ProjDraw(Projectile *p, int t);
+void Blast(Projectile *p, int t);
+
void Shrink(Projectile *p, int t);
+void GrowFade(Projectile *p, int t);
int bullet_flare_move(Projectile *p, int t);
void Fade(Projectile *p, int t);
diff --git a/src/stage.c b/src/stage.c
index 91754112..b2808947 100644
--- a/src/stage.c
+++ b/src/stage.c
@@ -110,6 +110,8 @@ void draw_hud() {
sprintf(buf, "%i fps", global.fps.show_fps);
draw_text(AL_Right, SCREEN_W, SCREEN_H-20, buf, _fonts.standard);
+
+ glDisable(GL_STENCIL_TEST);
}
void stage_draw() {
@@ -126,9 +128,9 @@ void stage_draw() {
player_draw(&global.plr);
+ draw_items();
draw_projectiles(global.projs);
draw_enemies(global.enemies);
- draw_items();
draw_lasers();
if(global.boss)
diff --git a/src/stage.h b/src/stage.h
index ae8062a8..cc1b5fab 100644
--- a/src/stage.h
+++ b/src/stage.h
@@ -8,9 +8,21 @@
#ifndef STAGE_H
#define STAGE_H
-#define TIMER(ptr) int *__timep = ptr; int _i;
+/* taisei's strange macro language.
+ *
+ * sorry, I guess it is bad style, but I hardcode everything and in that case
+ * you'll find yourself soon in a situation where you have to spread your
+ * coherent thoughts over frames using masses of redundant ifs.
+ * I've just invented this thingy to keep track of my sanity.
+ *
+ */
+
+#define TIMER(ptr) int *__timep = ptr; int _i, _ni;
#define AT(t) if(*__timep == t)
-#define FROM_TO(start,end,step) _i = (*__timep - start)/step; if(*__timep >= (start) && *__timep <= (end) && !(*__timep % (step)))
+#define FROM_TO(start,end,step) _i = (*__timep - (start))/(step); if(*__timep >= (start) && *__timep <= (end) && !((*__timep - (start)) % (step)))
+#define FROM_TO_INT(start, end, step, dur, istep) \
+ _i = (*__timep - (start))/(step+dur); _ni = ((*__timep - (start)) % (step+dur))/istep; \
+ if(*__timep >= (start) && *__timep <= (end) && (*__timep - (start)) % ((dur) + (step)) <= dur && !((*__timep - (start)) % (istep)))
typedef void (*StageRule)(void);
diff --git a/src/stages/stage0.c b/src/stages/stage0.c
index 6215b8d3..d3243422 100644
--- a/src/stages/stage0.c
+++ b/src/stages/stage0.c
@@ -133,7 +133,7 @@ Boss *create_cirno() {
void stage0_enemy0(Enemy *e, int time) {
TIMER(&time);
AT(EVENT_DEATH) {
- spawn_item(e->pos, Power);
+ spawn_items(e->pos, 3,0,0,0);
return;
}
@@ -143,7 +143,7 @@ void stage0_enemy0(Enemy *e, int time) {
AT(60) {
int i = 0;
for(i = -1; i <= 1; i++)
- create_projectile1c("ball", e->pos, rgb(0.2, 0.3, 0.5), linear, 4*cexp(I*(carg(global.plr.pos - e->pos) + 0.2*i)));
+ create_projectile2c("crystal", e->pos, rgb(0.2, 0.3, 0.5), asymptotic, 2*cexp(I*(carg(global.plr.pos - e->pos) + 0.2*i)), 5);
e->moving = 1;
e->dir = creal(e->args[0]) < 0;
@@ -158,9 +158,7 @@ void stage0_enemy0(Enemy *e, int time) {
void stage0_enemy1(Enemy *e, int time) {
TIMER(&time);
AT(EVENT_DEATH) {
- spawn_item(e->pos, Power);
- spawn_item(e->pos, Power);
- spawn_item(e->pos, Point);
+ spawn_items(e->pos, 2,2,0,0);
return;
}
@@ -169,15 +167,14 @@ void stage0_enemy1(Enemy *e, int time) {
FROM_TO(60,100,2) {
e->args[0] = 0.5*e->args[0];
- create_projectile1c("rice", e->pos, rgb(0.2, 0.4, 0.8), linear, 3*cexp(I*M_PI/10*_i));
+ create_projectile2c("rice", e->pos, rgb(0.6, 0.2, 0.7), asymptotic, 2*cexp(I*M_PI/10*_i), _i/2.0);
}
- FROM_TO(90, 500, 60) {
- int i;
- for(i = 4; i < 8; i++)
- create_projectile1c("ball", e->pos, rgb(0.2,0.4,0.8), linear, i*cexp(I*carg(global.plr.pos- e->pos)));
- }
+ FROM_TO(90, 500, 20);
+ if(!(_i % 9))
+ create_projectile2c("thickrice", e->pos, rgb(0.2, 0.4, 0.8), asymptotic, (1+frand()*3)*cexp(I*carg(global.plr.pos - e->pos)), 3);
+
FROM_TO(500, 900, 1)
e->args[0] += 0.03*e->args[1] - 0.04I;
}
@@ -185,7 +182,7 @@ void stage0_enemy1(Enemy *e, int time) {
void stage0_enemy2(Enemy *e, int time) {
TIMER(&time);
AT(EVENT_DEATH) {
- spawn_item(e->pos, Point);
+ spawn_items(e->pos, frand()>0.5, frand()>0.2,0,0);
return;
}
@@ -194,6 +191,58 @@ void stage0_enemy2(Enemy *e, int time) {
}
+void stage0_enemy3(Enemy *e, int t) {
+ TIMER(&t);
+ AT(EVENT_DEATH) {
+ spawn_items(e->pos, 2,1,0,0);
+ return;
+ }
+
+ e->pos = e->pos0 + e->args[0]*t + e->args[1]*t*t;
+
+ FROM_TO(10,1000,1)
+ if(frand() > 0.98)
+ create_projectile1c("ball", e->pos, rgb(0.8,0.8,0.4), linear, (1+frand())*cexp(I*carg(global.plr.pos - e->pos)));
+}
+
+void stage0_enemy4(Enemy *e, int t) {
+ TIMER(&t);
+ AT(EVENT_DEATH) {
+ spawn_items(e->pos, 3,4,0,0);
+ return;
+ }
+
+ FROM_TO(0, 150, 1)
+ e->pos += (e->args[0] - e->pos)*0.02;
+
+ FROM_TO_INT(150, 550, 40, 40, 2)
+ create_projectile2c("rice", e->pos, rgb(0.6, 0.2, 0.7), asymptotic, 2*cexp(I*M_PI/10*_ni), _ni/2.0);
+
+ FROM_TO(560,1000,1)
+ e->pos += e->args[1];
+}
+
+void stage0_enemy5(Enemy *e, int t) {
+ TIMER(&t);
+ AT(EVENT_DEATH) {
+ spawn_items(e->pos, 3,4,0,0);
+ return;
+ }
+
+ FROM_TO(0, 50, 1)
+ e->pos += 2I;
+
+ FROM_TO_INT(60, 300, 70, 40, 12) {
+ int i;
+ for(i = -1; i <= 1; i++)
+ create_projectile1c("crystal", e->pos, rgb(0.2, 0.3, 0.5), linear, 2.5*cexp(I*(carg(global.plr.pos - e->pos) + i/5.0)));
+ }
+
+ FROM_TO(320, 700, 1) {
+ e->args[1] += 0.03;
+ e->pos += e->args[0]*e->args[1] + 1.4I;
+ }
+}
void stage0_events() {
if(global.dialog)
return;
@@ -211,10 +260,28 @@ void stage0_events() {
}
FROM_TO(400, 460, 50)
- create_enemy2c(VIEWPORT_W*_i + VIEWPORT_H/3*I, 15, Fairy, stage0_enemy1, 2-4*_i-0.3I, 1-2*_i);
+ create_enemy2c(VIEWPORT_W*_i + VIEWPORT_H/3*I, 25, Fairy, stage0_enemy1, 2-4*_i-0.3I, 1-2*_i);
FROM_TO(380, 1000, 20)
- create_enemy2c(VIEWPORT_W*(_i&1) + rand()/(float)RAND_MAX*100I + 70I, 5, Swirl, stage0_enemy2, 3.5*(1-2*(_i&1)), rand()/(float)RAND_MAX*7I);
+ create_enemy2c(VIEWPORT_W*(_i&1) + frand()*100I + 70I, 2, Swirl, stage0_enemy2, 3.5*(1-2*(_i&1)), frand()*7I);
+
+ FROM_TO(1100, 1600, 20)
+ create_enemy2c(VIEWPORT_W/3, 3, Swirl, stage0_enemy3, 4I, 0.06);
+
+ FROM_TO(1500, 2000, 20)
+ create_enemy2c(VIEWPORT_W+200I, 3, Swirl, stage0_enemy3, -2, -0.04-0.03I);
+
+ FROM_TO(1250, 1800, 60)
+ create_enemy1c(VIEWPORT_W/2 + frand()*500-250 , 8, Fairy, stage0_enemy0, frand()*2-1);
+
+ FROM_TO(1700, 2700, 300)
+ create_enemy2c(VIEWPORT_W/2, 35, Fairy, stage0_enemy4, VIEWPORT_W/4 + VIEWPORT_W/2*frand()+200I, 3-6*(frand()>0.5)+frand()*2I);
+
+ FROM_TO(2000,2800, 200) {
+ int i;
+ for(i = 0; i < 5; i++)
+ create_enemy1c(VIEWPORT_W/4 + VIEWPORT_H/10*i, 8, Fairy, stage0_enemy5, i - 2.5);
+ }
// if(!(global.timer % 100))
// create_laser(LaserCurve, 300, 300, 60, 500, ((ColorA){0.6,0.6,1,0.4}), lolsin, 0);
}