taisei/src/stages/stage6.c
2017-10-10 15:27:10 +03:00

326 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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 "stage6.h"
#include "stage6_events.h"
#include "stage.h"
#include "stageutils.h"
#include "global.h"
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
* To add, remove, or reorder spells, see this stage's header file.
*/
struct stage6_spells_s stage6_spells = {
.scythe = {
.occams_razor = {{ 0, 1, 2, 3}, AT_Spellcard, "Newton Sign ~ Occams razor", 50, 60000,
elly_newton, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
.orbital_clockwork = {{24, 25, 26, 27}, AT_Spellcard, "Kepler Sign ~ Orbital Clockwork", 45, 60000,
elly_kepler, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
.wave_theory = {{ 4, 5, 6, 7}, AT_Spellcard, "Maxwell Sign ~ Wave Theory", 25, 30000,
elly_maxwell, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
},
.baryon = {
.many_world_interpretation = {{ 8, 9, 10, 11}, AT_Spellcard, "Eigenstate ~ Many-World Interpretation", 40, 60000,
elly_eigenstate, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
.spacetime_curvature = {{12, 13, 14, 15}, AT_Spellcard, "Ricci Sign ~ Spacetime Curvature", 50, 90000,
elly_ricci, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
.higgs_boson_uncovered = {{16, 17, 18, 19}, AT_Spellcard, "LHC ~ Higgs Boson Uncovered", 50, 60000,
elly_lhc, elly_spellbg_modern, BOSS_DEFAULT_GO_POS}
},
.extra = {
.curvature_domination = {{ 0, 1, 2, 3}, AT_ExtraSpell, "Forgotten Universe ~ Curvature Domination", 60, 60000,
elly_curvature, elly_spellbg_modern, BOSS_DEFAULT_GO_POS}
},
.final = {
.theory_of_everything = {{20, 21, 22, 23}, AT_SurvivalSpell, "Tower of Truth ~ Theory of Everything", 70, 40000,
elly_theory, elly_spellbg_modern, BOSS_DEFAULT_GO_POS}
},
};
static Stage3D bgcontext;
static int fall_over;
enum {
NUM_STARS = 100
};
static float starpos[3*NUM_STARS];
Vector **stage6_towerwall_pos(Vector pos, float maxrange) {
Vector p = {0, 0, -220};
Vector r = {0, 0, 300};
Vector **list = linear3dpos(pos, maxrange, p, r);
int i;
for(i = 0; list[i] != NULL; i++) {
if((*list[i])[2] > 0)
(*list[i])[1] = -90000;
}
return list;
}
void stage6_towerwall_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, get_tex("stage6/towerwall")->gltex);
Shader *s = get_shader("tower_wall");
glUseProgram(s->prog);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
// glRotatef(90, 1,0,0);
glScalef(30,30,30);
draw_model("towerwall");
glPopMatrix();
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
}
Vector **stage6_towertop_pos(Vector pos, float maxrange) {
Vector p = {0, 0, 70};
return single3dpos(pos, maxrange, p);
}
void stage6_towertop_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, get_tex("stage6/towertop")->gltex);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
glScalef(28,28,28);
draw_model("towertop");
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
Vector **stage6_skysphere_pos(Vector pos, float maxrange) {
return single3dpos(pos, maxrange, bgcontext.cx);
}
void stage6_skysphere_draw(Vector pos) {
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
Shader *s = get_shader("stage6_sky");
glUseProgram(s->prog);
glBindTexture(GL_TEXTURE_2D, get_tex("stage6/sky")->gltex);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]-30);
glScalef(150,150,150);
draw_model("skysphere");
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
for(int i = 0; i < NUM_STARS; i++) {
glPushMatrix();
float x = starpos[3*i+0], y = starpos[3*i+1], z = starpos[3*i+2];
glColor4f(0.9,0.9,1,0.8*z);
glTranslatef(x,y,z);
glRotatef(180/M_PI*acos(starpos[3*i+2]),-y,x,0);
glScalef(1./4000,1./4000,1./4000);
draw_texture(0,0,"part/lasercurve");
glPopMatrix();
}
glPopMatrix();
glColor4f(1,1,1,1);
glEnable(GL_DEPTH_TEST);
}
void stage6_draw(void) {
set_perspective(&bgcontext, 100, 9000);
draw_stage3d(&bgcontext, 10000);
if(fall_over) {
int t = global.frames - fall_over;
TIMER(&t);
FROM_TO(0, 240, 1) {
bgcontext.cx[0] += 0.02*cos(M_PI/180*bgcontext.crot[2]+M_PI/2)*_i;
bgcontext.cx[1] += 0.02*sin(M_PI/180*bgcontext.crot[2]+M_PI/2)*_i;
}
FROM_TO(150, 1000, 1) {
bgcontext.crot[0] -= 0.02*(global.frames-fall_over-150);
if(bgcontext.crot[0] < 0)
bgcontext.crot[0] = 0;
}
if(t >= 190)
bgcontext.cx[2] -= max(6, 0.05*(global.frames-fall_over-150));
FROM_TO(300, 470,1) {
bgcontext.cx[0] -= 0.01*cos(M_PI/180*bgcontext.crot[2]+M_PI/2)*_i;
bgcontext.cx[1] -= 0.01*sin(M_PI/180*bgcontext.crot[2]+M_PI/2)*_i;
}
if(t > 470)
bgcontext.cx[0] += 1-2*frand();
}
float w = 0.002;
float f = 1, g = 1;
if(global.timer > 3273) {
f = max(0, f-0.01*(global.timer-3273));
}
if(global.timer > 3628)
g = max(0, g-0.01*(global.timer - 3628));
bgcontext.cx[0] += -230*w*f*sin(w*global.frames-M_PI/2);
bgcontext.cx[1] += 230*w*f*cos(w*global.frames-M_PI/2);
bgcontext.cx[2] += w*f*140/M_PI;
bgcontext.crot[2] += 180/M_PI*g*w;
}
void start_fall_over(void) { //troll
fall_over = global.frames;
}
void stage6_start(void) {
init_stage3d(&bgcontext);
fall_over = 0;
add_model(&bgcontext, stage6_skysphere_draw, stage6_skysphere_pos);
add_model(&bgcontext, stage6_towertop_draw, stage6_towertop_pos);
add_model(&bgcontext, stage6_towerwall_draw, stage6_towerwall_pos);
for(int i = 0; i < NUM_STARS; i++) {
float x,y,z,r;
do {
x = nfrand();
y = nfrand();
z = frand();
r = sqrt(x*x+y*y+z*z);
} while(0 < r < 1);
starpos[3*i+0]= x/r;
starpos[3*i+1]= y/r;
starpos[3*i+2]= z/r;
}
bgcontext.cx[1] = -230;
bgcontext.crot[0] = 90;
bgcontext.crot[2] = -40;
// for testing
// bgcontext.cx[0] = 80;
// bgcontext.cx[1] = -215;
// bgcontext.cx[2] = 295;
// bgcontext.crot[0] = 90;
// bgcontext.crot[2] = 381.415100;
//
}
void stage6_preload(void) {
preload_resources(RES_BGM, RESF_OPTIONAL, "stage6", "stage6boss", NULL);
preload_resources(RES_TEXTURE, RESF_DEFAULT,
"stage6/baryon_connector",
"stage6/baryon",
"stage6/scythecircle",
"stage6/scythe",
"stage6/sky",
"stage6/spellbg_chalk",
"stage6/spellbg_classic",
"stage6/spellbg_modern",
"stage6/towertop",
"stage6/towerwall",
"dialog/elly",
NULL);
preload_resources(RES_SHADER, RESF_DEFAULT,
"tower_wall",
"stage6_sky",
NULL);
preload_resources(RES_ANIM, RESF_DEFAULT,
"elly",
NULL);
preload_resources(RES_MODEL, RESF_DEFAULT,
"towerwall",
"towertop",
"skysphere",
NULL);
}
void stage6_end(void) {
free_stage3d(&bgcontext);
}
void elly_intro(Boss*, int);
void elly_unbound(Boss*, int);
void stage6_spellpractice_events(void) {
TIMER(&global.timer);
AT(0) {
skip_background_anim(&bgcontext, stage6_draw, 3800, &global.timer, &global.frames);
global.boss = stage6_spawn_elly(BOSS_DEFAULT_SPAWN_POS);
AttackInfo *s = global.stage->spell;
char go = true;
if(STG6_SPELL_NEEDS_SCYTHE(s)) {
boss_add_attack(global.boss, AT_Move, "Catch the Scythe", 2, 0, elly_intro, NULL);
go = false;
} else if(STG6_SPELL_NEEDS_BARYON(s)) {
boss_add_attack(global.boss, AT_Move, "Unbound", 3, 0, elly_unbound, NULL);
go = false;
} else if(s == &stage6_spells.final.theory_of_everything) {
start_fall_over();
skip_background_anim(&bgcontext, stage6_draw, 300, &global.timer, &global.frames);
}
boss_add_attack_from_info(global.boss, global.stage->spell, go);
boss_start_attack(global.boss, global.boss->attacks);
start_bgm("stage6boss");
}
if(!global.boss) {
killall(global.enemies);
}
}
ShaderRule stage6_shaders[] = { NULL };
StageProcs stage6_procs = {
.begin = stage6_start,
.preload = stage6_preload,
.end = stage6_end,
.draw = stage6_draw,
.event = stage6_events,
.shader_rules = stage6_shaders,
.spellpractice_procs = &stage6_spell_procs,
};
StageProcs stage6_spell_procs = {
.preload = stage6_preload,
.begin = stage6_start,
.end = stage6_end,
.draw = stage6_draw,
.event = stage6_spellpractice_events,
.shader_rules = stage6_shaders,
};