/*! -------------------------------------------------------------------- \file missle.cpp \brief Class to render a missle \author Roy Thompson \date 2002-09-20 $Updated: qsb $ $Date: 2002/12/12 07:22:10 $ -------------------------------------------------------------------- */ #include #include #include #include #include #include "missle.h" #include "sound.h" #include typedef struct materialStruct { GLfloat ambient[4]; GLfloat diffuse[4]; GLfloat specular[4]; GLfloat shininess; } materialStruct; extern materialStruct brassMaterials; extern materialStruct redPlasticMaterials; Missle *Missle::s_pMissle = NULL; //--------------------------------------------------------------------- // Missle // Method: Constructor // //! Make the pointer to the first missle NULL // //--------------------------------------------------------------------- Missle::Missle() { frontList = NULL; } //--------------------------------------------------------------------- // Missle // Method: AddMissle // //! Adds a new missle into the world with specified starting position, // vector direction, and speed // //--------------------------------------------------------------------- void Missle::AddMissle(Math3d::M3d pos, Math3d::M3d dir, float spd, float radius, float damage) { theSound.PlaySound(Sound::FIRE); Missles *ptr = frontList; Missles *newMissle = new Missles; newMissle->speed = spd; newMissle->position = pos; newMissle->lastpos = pos; newMissle->direction = dir; newMissle->next = NULL; newMissle->distance = 0.0; newMissle->radius = radius; newMissle->damage = damage; newMissle->active = true; if (frontList == NULL) frontList = newMissle; else { while (ptr->next != NULL) ptr = ptr->next; ptr->next = newMissle; } } //--------------------------------------------------------------------- // Missle // Method: Render // //! Renders all the missles currently in the system and removes ones // that are no longer valid // //--------------------------------------------------------------------- void Missle::Render() { for(Missles *ptr = frontList; ptr != NULL; ptr = ptr->next) { if (ptr->active) { glPushMatrix(); glDisable(GL_TEXTURE_2D); glTranslatef(ptr->position[0], ptr->position[1], ptr->position[2]); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, redPlasticMaterials.ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, redPlasticMaterials.diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, redPlasticMaterials.specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, redPlasticMaterials.shininess); // In this case my missle is actually just a sphere, but this could // easily be changed to something that looks more like a missle glutSolidSphere(ptr->radius*0.5, 20, 20); glEnable(GL_TEXTURE_2D); glPopMatrix(); } } } void Missle::UpdateState(float timeElapsed) { Missles *tempptr; // update the position of all missles for (Missles *ptr = frontList; ptr != NULL; ptr = ptr->next) { if (ptr->active) { ptr->lastpos = ptr->position; ptr->position += ptr->direction * timeElapsed * ptr->speed; ptr->distance += timeElapsed * ptr->speed; } if (ptr-> distance > 800.0) ptr->active = false; } // delete missles that are no longer active for (Missles *ptr = frontList; ptr != NULL && !ptr->active;) { tempptr = ptr; ptr = ptr->next; frontList = ptr; delete tempptr; } } float Missle::IsCollision(BoundingVol bvol) { int inc = 10; for (Missles *ptr = frontList; ptr != NULL; ptr=ptr->next) { if (ptr->active) { Math3d::M3d moveVec = ptr->position - ptr->lastpos; for (int i=0; i<=inc; i++) { Math3d::M3d curpos = ptr->position + (moveVec * ((float)i/inc)); float sumr = ptr->radius + bvol.radius; // calculate the distance b/w the centers float x = curpos[0] - bvol.center[0]; x *= x; float y = curpos[1] - bvol.center[1]; y *= y; float z = curpos[2] - bvol.center[2]; z *= z; float dist = sqrt(x+y+z); // cout << "Sum: " << sumr << ", dist: " << dist << endl; if (dist <= sumr) { ptr->active = false; return ptr->damage; } } } } return -1.0; } void Missle::Restart() { Missles *tempptr; for (Missles *ptr = frontList; ptr != NULL;) { tempptr = ptr; ptr = ptr->next; frontList = ptr; delete tempptr; } }