taisei/src/laser.c
Andrew "Akari" Alexeyew 71aaf68105 spell test
2012-07-24 17:45:58 +03:00

185 lines
4.5 KiB
C

/*
* 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 "laser.h"
#include "global.h"
#include "list.h"
Laser *create_laser_p(LaserType type, complex pos, complex dir, int time, int deathtime, Color *color, LaserRule rule, complex a0, complex a1, complex a2, complex a3) {
Laser *l = create_element((void **)&global.lasers, sizeof(Laser));
l->type = type;
l->birthtime = global.frames;
l->time = time;
l->deathtime = deathtime;
l->pos = pos;
l->dir = dir;
l->rule = rule;
l->color = color;
l->args[0] = a0;
l->args[1] = a1;
l->args[2] = a2;
l->args[3] = a3;
return l;
}
void draw_laser_line(Laser *laser) {
float width = cabs(laser->dir);
if(global.frames - laser->birthtime < laser->time*3/5.0)
width = 2;
else if(global.frames - laser->birthtime < laser->time)
width = 2 + (width - 2)/laser->time * (global.frames - laser->birthtime);
else if(global.frames - laser->birthtime > laser->deathtime-20)
width = width - width/20 * (global.frames - laser->birthtime - laser->deathtime + 20);
glPushMatrix();
glTranslatef(creal(laser->pos), cimag(laser->pos),0);
glRotatef(carg(laser->dir)*180/M_PI,0,0,1);
glBindTexture(GL_TEXTURE_2D, get_tex("part/lasercurve")->gltex);
glColor4fv((float *)laser->color);
glTranslatef(500, 0, 0);
glScalef(1000,width+4,1);
draw_quad();
glColor3f(1,1,1);
glScalef(1,0.8,1);
draw_quad();
glPopMatrix();
}
void draw_laser_curve(Laser *laser) {
Texture *tex = get_tex("part/lasercurve");
glBindTexture(GL_TEXTURE_2D, tex->gltex);
glColor4fv((float *)laser->color);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
float t = global.frames - laser->birthtime - laser->time;
if(t < 0)
t = 0;
for(; t < global.frames - laser->birthtime && t <= laser->deathtime; t += 0.5) {
complex pos = laser->rule(laser,t);
glPushMatrix();
float t1 = t - (global.frames - laser->birthtime - laser->time/2);
float tail = laser->time/1.9;
float s = -0.75/pow(tail,2)*(t1-tail)*(t1+tail);
glTranslatef(creal(pos), cimag(pos), 0);
float wq = ((float)tex->w)/tex->truew;
float hq = ((float)tex->h)/tex->trueh;
glScalef(s*tex->w*wq,s*tex->h*hq,s);
draw_quad();
glPopMatrix();
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1,1,1,1);
}
void draw_lasers() {
Laser *laser;
for(laser = global.lasers; laser; laser = laser->next) {
glEnable(GL_TEXTURE_2D);
if(laser->type == LT_Line)
draw_laser_line(laser);
else
draw_laser_curve(laser);
glDisable(GL_TEXTURE_2D);
}
}
void delete_lasers() {
delete_all_elements((void **)&global.lasers, delete_element);
}
void process_lasers() {
Laser *laser = global.lasers, *del = NULL;
while(laser != NULL) {
int c = 0;
if(laser->type == LT_Line) {
if(laser->rule)
laser->rule(laser, global.frames - laser->birthtime);
c = collision_laser_line(laser);
} else {
c = collision_laser_curve(laser);
}
if(c && global.frames - laser->birthtime > laser->time)
player_death(&global.plr);
if(global.frames - laser->birthtime > laser->deathtime + laser->time) {
del = laser;
laser = laser->next;
delete_element((void **)&global.lasers, del);
if(laser == NULL) break;
} else {
laser = laser->next;
}
}
}
int collision_laser_line(Laser *l) {
Player *plr = &global.plr;
float x = creal(l->pos) + creal(l->dir)/cimag(l->dir)*(cimag(plr->pos) - cimag(l->pos));
if(fabs(creal(plr->pos) - x) < fabs(creal(l->dir*I)/2))
return 1;
else
return 0;
}
int collision_laser_curve(Laser *l) {
float t = global.frames - l->birthtime - l->time;
if(t < 0)
t = 0;
for(; t < global.frames - l->birthtime && t <= l->deathtime; t+=2) {
complex pos = l->rule(l,t);
if(cabs(pos - global.plr.pos) < 5)
return 1;
}
return 0;
}
complex las_linear(Laser *l, float t) {
return l->pos + l->args[0]*t;
}
complex las_accel(Laser *l, float t) {
return l->pos + l->args[0]*t + 0.5*l->args[1]*t*t;
}
complex las_sine(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase
double s = (l->args[2] * t + l->args[3]);
return l->pos + cexp(I * (carg(l->args[0]) + l->args[1] * sin(s) / s)) * t * cabs(l->args[0]);
}
complex las_sine_expanding(Laser *l, float t) { // [0] = velocity; [1] = sine amplitude; [2] = sine frequency; [3] = sine phase
double s = (l->args[2] * t + l->args[3]);
return l->pos + cexp(I * (carg(l->args[0]) + l->args[1] * sin(s))) * t * cabs(l->args[0]);
}