/* Copyright (C) 2000 Xavier Hosxe This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "explosion.hpp" extern GLfloat myship_meshes[]; extern GLfloat bandit1_meshes[]; extern GLfloat cube_meshes[]; Explosion::Explosion(Sprite *sprite,int size, int sound,int pieces, float x, float y, float z) : Sprite(sprite->getList(), TYPE_EXPLOSION, sprite->getX(), sprite->getY(), sprite->getZ()) { dz_ = -.1; nSmoke = random()%3; if (x!=99) { x_=x; } if (y!=99) { y_=y; } if (z!=99) { z_=z; } sizex_=sizey_=size; currentSize_=size/4; x1_=(random()%10)/15+.25; x3_=(random()%10)/15+.25; x2_=1-x1_; x4_=1-x3_; r1_ = random()%90; from_ = sprite->getType(); pieces_ = pieces; if (pieces_) { if (GLvar->details>0) { ExplosionMark *mark; mark = new ExplosionMark(this,size); mlist->Add(mark); } PieceOfShip *piece; piece = new PieceOfShip(this,size*2 + size*2*(GLvar->details==1) +size*3*(GLvar->details==2)); mlist->Add(piece); } if (sound!=0) { SpritePlaySample((type_samples)(SAMPLE_EXPLODE1 +random()%2)); } } void Explosion::draw() { glPushMatrix(); glTranslatef(x_ , y_ , z_); glRotatef(r1_,0,0,1); if (GLvar->camera==2) { glRotatef(90,1,0,0); } glBlendFunc(GL_SRC_ALPHA , GL_ONE); glDepthFunc(GL_ALWAYS); glDepthMask(0); glEnable(GL_TEXTURE_2D); if (pieces_ && GLvar->details>0) { glBindTexture(GL_TEXTURE_2D, GLvar->texture_fumee[nSmoke]); glColor4f( 1 , 1.0 , 1.0 , 1.0 - (currentSize_/sizey_)); glBegin(GL_QUADS); glTexCoord2f(1,1); glVertex3f(currentSize_*1.0 ,currentSize_*1.0,0); glTexCoord2f(1,0); glVertex3f(currentSize_*1.0 ,-currentSize_*1.0,0); glTexCoord2f(0,0); glVertex3f(-currentSize_*1.0 ,-currentSize_*1.0,0); glTexCoord2f(0,1); glVertex3f(-currentSize_*1.0 ,currentSize_*1.0,0); glEnd(); } glDisable(GL_TEXTURE_2D); glBegin(GL_TRIANGLE_FAN); glColor4f(1 , 1 , 0 , 1 - (currentSize_/sizey_)); glVertex3f(0 ,0,0); glColor4f(1 , 0 , 0 , 0.0); glVertex3f(currentSize_*2.5*x3_ ,currentSize_*2.5*x3_,0); glVertex3f(currentSize_*2.5*x2_ ,-currentSize_*2.5*x2_,0); glVertex3f(-currentSize_*2.5*x1_ ,-currentSize_*2.5*x1_,0); glVertex3f(-currentSize_*2.5*x4_ ,currentSize_*2.5*x4_,0); glVertex3f(currentSize_*2.5*x3_ ,currentSize_*2.5*x3_,0); glEnd(); glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA); glDepthMask(1); glDepthFunc(GL_LEQUAL); glPopMatrix(); } void Explosion::collision(Sprite*contact) { } void Explosion::move() { Sprite::move(); currentSize_+=.07*GLvar->global_timeadjustment; if (currentSize_>sizey_) { dead_=1; } } // ========= PieceOfShip PieceOfShip::PieceOfShip(Sprite *sprite,int size) : Sprite(sprite->getList(), TYPE_EXPLOSION, sprite->getX(), sprite->getY(), sprite->getZ()) { int i; size_=size; cptAlive_=size; ax_ = new float[size]; ay_ = new float[size]; az_ = new float[size]; adx_ = new float[size]; ady_ = new float[size]; adz_ = new float[size]; acolor_= new float[size]; asizex_ = new float[size]; asizey_ = new float[size]; aalpha_ = new float[size]; arotate_ = new float[size]; alive_ = new short[size]; atype_ = new int[size]; atexture_ = new int[size]; for (i=0;igetX(); ay_[i]=sprite->getY(); az_[i]=sprite->getZ(); if (atype_[i]==0) { adx_[i]= (float)(random()%20)/100 -.1; adz_[i]= (float)((random()&1)==0?-1:1)*sqrt((.01-adx_[i]*adx_[i]))-.1; ady_[i]= 0.0f; } else { adx_[i]= (float)(random()%40)/100 -.2; ady_[i]= (float)(random()%100)/300; adz_[i]= (float)(random()%40)/100 -.2; } acolor_[i]= (float)(random()%100)/200+.5; asizex_ [i]= (float)(random()%150)/1500 + .025 ; asizey_ [i]= (float)(random()%150)/1500 + .025 ; aalpha_[i]=1; atexture_[i]=random()%100; arotate_[i]=0; } from_= ((Explosion*)sprite)->getFrom(); } PieceOfShip::~PieceOfShip() { delete []ax_; delete []ay_; delete []az_; delete []adx_; delete []ady_; delete []adz_; delete []acolor_; delete []asizex_; delete []asizey_; delete []aalpha_; delete []arotate_; delete []atexture_; delete []atype_; delete []alive_; } void PieceOfShip::drawShadowable() { int i; float pColor[] = {1.0,1.0,1.0,1.0}; glPushMatrix(); glDisable(GL_CULL_FACE); for (i=0;itexture_sphere); glBegin(GL_QUADS); for (i=0;i.5?1.0:2*aalpha_[i]); else pColor[3] = (1-aalpha_[i])*4; glColor4fv(pColor); float adj = 2-aalpha_[i]; if (GLvar->camera==1) { glTexCoord2f(0.0f,0.0f);glVertex3f(ax_[i]-asizex_[i]*2*adj ,.5-asizey_[i]*2*adj,az_[i]); glTexCoord2f(1.0f,0.0f);glVertex3f(ax_[i]-asizex_[i]*2*adj ,.5+asizey_[i]*2*adj,az_[i]); glTexCoord2f(1.0f,1.0f);glVertex3f(ax_[i]+asizex_[i]*2*adj ,.5+asizey_[i]*2*adj,az_[i]); glTexCoord2f(0.0f,1.0f);glVertex3f(ax_[i]+asizex_[i]*2*adj ,.5-asizey_[i]*2*adj,az_[i]); } else if (GLvar->camera==2) { glTexCoord2f(0.0f,0.0f);glVertex3f(ax_[i]-asizex_[i]*2*adj ,ay_[i],az_[i]-asizey_[i]*2*adj); glTexCoord2f(1.0f,0.0f);glVertex3f(ax_[i]-asizex_[i]*2*adj ,ay_[i],az_[i]+asizey_[i]*2*adj); glTexCoord2f(1.0f,1.0f);glVertex3f(ax_[i]+asizex_[i]*2*adj ,ay_[i],az_[i]+asizey_[i]*2*adj); glTexCoord2f(0.0f,1.0f);glVertex3f(ax_[i]+asizex_[i]*2*adj ,ay_[i],az_[i]-asizey_[i]*2*adj); } } glEnd(); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,GLvar->blanc_diffuse); glDepthMask(1); glEnable(GL_LIGHTING); glDisable(GL_BLEND); switch(from_) { case TYPE_MY_SPACE_SHIP: glBindTexture(GL_TEXTURE_2D, GLvar->texture_myship); for (i=0;itexture_bandit1); for (i=0;itexture_bandit2); for (i=0;imarron_diffuse); for (i=0;iblanc_diffuse); break; case TYPE_TANK: glColor4f(acolor_[i]/4,acolor_[i]/1.5,acolor_[i]/4,aalpha_[i]); // glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,marron_diffuse); break; case TYPE_CUBE: glBindTexture(GL_TEXTURE_2D, GLvar->texture_building); for (i=0;iglobal_timeadjustment; ay_[i]-=.002*GLvar->global_timeadjustment; if ((ay_[i]<-.3) && (alive_[i]==0)) { cptAlive_--; alive_[i]=-1; } continue; } arotate_[i]+=10*GLvar->global_timeadjustment; if (atype_[i]==0) { aalpha_[i] -=.02*GLvar->global_timeadjustment; ady_[i]-=0.004*GLvar->global_timeadjustment; } else { ady_[i]-=0.006*GLvar->global_timeadjustment; } ax_[i]+=adx_[i]*GLvar->global_timeadjustment; ay_[i]+=ady_[i]*GLvar->global_timeadjustment; az_[i]+=adz_[i]*GLvar->global_timeadjustment; if ((ay_[i]<0) && (ax_[i]<12) && (ax_[i]>-12) && (atype_[i]!=0)) { if (ady_[i]>-.06) { ay_[i]=0; alive_[i]=0; } else { ay_[i] = -ay_[i]; ady_[i]= -ady_[i]/2; } } if (ay_[i]<-40) { cptAlive_--; alive_[i]=-1; } if (aalpha_[i]<=0) { cptAlive_--; alive_[i]=-1; } } if (cptAlive_<=0) { dead_=1; } } // ======== ExplosionJustSmoke ExplosionJustSmoke::ExplosionJustSmoke(Sprite *sprite,float size) : Sprite(sprite->getList(), TYPE_EXPLOSION, sprite->getX(), sprite->getY(), sprite->getZ()) { nSmoke = random()%3; sizex_=sizey_=size; currentSize_=size/4; x1_=(random()%10)/15+.25; x3_=(random()%10)/15+.25; x2_=1-x1_; x4_=1-x3_; r1_ = random()%90; } void ExplosionJustSmoke::draw() { glPushMatrix(); glTranslatef(x_ , y_ , z_); glRotatef(r1_,0,0,1); if (GLvar->camera==2) { glRotatef(90,1,0,0); } glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_ALWAYS); glDepthMask(0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, GLvar->texture_fumee[nSmoke]); glColor4f( 1 , 1.0 , 1.0 , 1.0 - (currentSize_/sizey_)); glBegin(GL_QUADS); glTexCoord2f(1,1); glVertex3f(currentSize_*1.0 ,currentSize_*1.0,0); glTexCoord2f(1,0); glVertex3f(currentSize_*1.0 ,-currentSize_*1.0,0); glTexCoord2f(0,0); glVertex3f(-currentSize_*1.0 ,-currentSize_*1.0,0); glTexCoord2f(0,1); glVertex3f(-currentSize_*1.0 ,currentSize_*1.0,0); glEnd(); glDisable(GL_TEXTURE_2D); glDepthMask(1); glDepthFunc(GL_LEQUAL); glPopMatrix(); } void ExplosionJustSmoke::collision(Sprite*contact) { } void ExplosionJustSmoke::move() { currentSize_+=.05*GLvar->global_timeadjustment; if (currentSize_>sizey_) { dead_=1; } } // ======== ExplosionMark ExplosionMark::ExplosionMark(Sprite *sprite,int size) : Sprite(sprite->getList(), TYPE_EXPLOSION, sprite->getX(), .005, sprite->getZ()) { dz_ = -.1; size_=size/3; } void ExplosionMark::draw() { glPushMatrix(); glTranslatef(x_ , 0.005 , z_); glColor4f(1,0,0,.6); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glDepthFunc(GL_ALWAYS); glDepthMask(0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, GLvar->texture_mark); glBegin(GL_QUADS); glTexCoord2f(1,0); glVertex3f(size_,0,-size_); glTexCoord2f(0,0); glVertex3f(-size_,0,-size_); glTexCoord2f(0,1); glVertex3f(-size_,0,size_); glTexCoord2f(1,1); glVertex3f(size_,0,size_); glEnd(); glDepthMask(1); glDisable(GL_TEXTURE_2D); glPopMatrix(); } void ExplosionMark::collision(Sprite*contact) { } void ExplosionMark::move() { Sprite::move(); if (z_<-3) { dead_=1; } } // ======== SpecialEffect1 SpecialEffect1::SpecialEffect1(Sprite *sprite, Diamond::Type type) : Sprite(sprite->getList(), TYPE_EXPLOSION, 0,0, 0) { int i; toFollow_ = sprite; diamondType_= type; switch (diamondType_) { case Diamond::POWER: nPart_= 9; break; case Diamond::BOMB: nPart_= 9; break; case Diamond::INVUL: nPart_= 12; break; case Diamond::POWERUP: nPart_= 16+GLvar->mySpaceShip->powerUp_; break; default: nPart_ = 0; break; } int oldPart = nPart_; nPart_/=(3-GLvar->details); pX_ = new float[nPart_]; pY_ = new float[nPart_]; pZ_ = new float[nPart_]; life_ = new float[nPart_]; maxLife_ = 0; for (i=0; imaxLife_) maxLife_ = life_[i]; } currentTime=0; if (!toFollow_->addListeningSprite(this)) { toFollow_=NULL; } } SpecialEffect1::~SpecialEffect1() { delete []pX_; delete []pY_; delete []pZ_; delete []life_; } void SpecialEffect1::draw() { int i; // printf("%f\n", draw); glPushMatrix(); glTranslatef(toFollow_->getX(), toFollow_->getY(), toFollow_->getZ()); //glDepthFunc(GL_ALWAYS); glBlendFunc(GL_SRC_ALPHA , GL_ONE); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, GLvar->texture_specialeffect1); glDisable(GL_LIGHTING); glDisable(GL_CULL_FACE); glBegin(GL_QUADS); for (i=0; ilife_[i]) { // printf("Skip %d\n", i); continue; } //Color4f(1,1,1, 1); glColor4f(1,1,1, 0); glTexCoord2f(1,0); glVertex3f(pX_[i]*3.5-.2, 7, pZ_[i]*3.5); glTexCoord2f(0,0); glVertex3f(pX_[i]*3.5+.2, 7, pZ_[i]*3.5); switch (diamondType_) { case Diamond::POWER: glColor4f(.2,.2,1, 1.0f-(float)(currentTime>life_[i]/2?(float)(currentTime-life_[i]/2.0f)/(life_[i]/2):(float)(life_[i]/2.0f-currentTime)/(life_[i]/2))); break; case Diamond::BOMB: glColor4f(1,1,0, 1.0f-(float)(currentTime>life_[i]/2?(float)(currentTime-life_[i]/2.0f)/(life_[i]/2):(float)(life_[i]/2.0f-currentTime)/(life_[i]/2))); break; case Diamond::INVUL: glColor4f(.2,1,.2, 1.0f-(float)(currentTime>life_[i]/2?(float)(currentTime-life_[i]/2.0f)/(life_[i]/2):(float)(life_[i]/2.0f-currentTime)/(life_[i]/2))); break; case Diamond::POWERUP: glColor4f(1,0,.6, 1.0f-(float)(currentTime>life_[i]/2?(float)(currentTime-life_[i]/2.0f)/(life_[i]/2):(float)(life_[i]/2.0f-currentTime)/(life_[i]/2))); break; } glTexCoord2f(0,.99); glVertex3f(pX_[i]+.2, 0, pZ_[i]); glTexCoord2f(1,.99); glVertex3f(pX_[i]-.2, 0, pZ_[i]); } glEnd(); glBlendFunc(GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA); // glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); glDisable(GL_TEXTURE_2D); glPopMatrix(); } void SpecialEffect1::collision(Sprite*contact) { } void SpecialEffect1::move() { currentTime+=GLvar->global_timeadjustment; // printf("%f\n", currentTime); if (currentTime>maxLife_) { dead_=1; } } void SpecialEffect1::receiveEvent(Sprite*sprite) { toFollow_=NULL; dead_ = 1; } void SpecialEffect1::iJustDied() { // printf("f3 - I'm 0x%x just died and i want 0x%x to remove me\n",this, toShot_); if (toFollow_!=NULL) { toFollow_->removeListeningSprite(this); } }