/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx 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, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Knecht co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY #include "executor/executor.h" #include "space_ship.h" #include "objModel.h" #include "resource_manager.h" #include "weapons/weapon_manager.h" #include "weapons/test_gun.h" #include "weapons/turret.h" #include "weapons/cannon.h" #include "factory.h" #include "key_mapper.h" using namespace std; CREATE_FACTORY(SpaceShip, CL_SPACE_SHIP); /** * creates the controlable Spaceship */ SpaceShip::SpaceShip() { this->init(); } /** * destructs the spaceship, deletes alocated memory */ SpaceShip::~SpaceShip () { } /** * loads a Spaceships information from a specified file. * @param fileName the name of the File to load the spaceship from (absolute path) */ SpaceShip::SpaceShip(const char* fileName) { this->init(); TiXmlDocument doc(fileName); if(!doc.LoadFile()) { PRINTF(2)("Loading file %s failed for spaceship.\n", fileName); return; } this->loadParams(doc.RootElement()); } /** * creates a new Spaceship from Xml Data * @param root the xml element containing spaceship data @todo add more parameters to load */ SpaceShip::SpaceShip(const TiXmlElement* root) { this->init(); if (root != NULL) this->loadParams(root); //weapons: Weapon* wpRight = new TestGun(0); wpRight->setName("testGun Right"); Weapon* wpLeft = new TestGun(1); wpLeft->setName("testGun Left"); Weapon* cannon = dynamic_cast(Factory::getFirst()->fabricate(CL_CANNON)); cannon->setName("BFG"); this->getWeaponManager()->addWeapon(wpLeft, 1, 0); this->getWeaponManager()->addWeapon(wpRight,1 ,1); this->getWeaponManager()->addWeapon(cannon, 0, 6); //this->getWeaponManager()->addWeapon(turret, 3, 0); this->getWeaponManager()->changeWeaponConfig(1); } /** * initializes a Spaceship */ void SpaceShip::init() { // this->setRelDir(Quaternion(M_PI, Vector(1,0,0))); this->setClassID(CL_SPACE_SHIP, "SpaceShip"); PRINTF(4)("SPACESHIP INIT\n"); bUp = bDown = bLeft = bRight = bAscend = bDescend = false; bFire = false; travelSpeed = 15.0; this->velocity = Vector(0.0,0.0,0.0); this->velocityDir = Vector(1.0,0.0,0.0); // GLGuiButton* button = new GLGuiPushButton(); // button->show(); // button->setLabel("orxonox"); // button->setBindNode(this); //add events to the eventlist registerEvent(KeyMapper::PEV_UP); registerEvent(KeyMapper::PEV_DOWN); registerEvent(KeyMapper::PEV_LEFT); registerEvent(KeyMapper::PEV_RIGHT); registerEvent(KeyMapper::PEV_FIRE1); registerEvent(KeyMapper::PEV_NEXT_WEAPON); registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON); registerEvent(SDLK_PAGEUP); registerEvent(SDLK_PAGEDOWN); this->getWeaponManager()->setSlotCount(7); this->getWeaponManager()->setSlotPosition(0, Vector(-2.6, .1, -3.0)); this->getWeaponManager()->setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); this->getWeaponManager()->setSlotPosition(1, Vector(-2.6, .1, 3.0)); this->getWeaponManager()->setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); this->getWeaponManager()->setSlotPosition(2, Vector(-1.5, .5, -.5)); this->getWeaponManager()->setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0))); this->getWeaponManager()->setSlotPosition(3, Vector(-1.5, .5, .5)); this->getWeaponManager()->setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0))); this->getWeaponManager()->setSlotPosition(4, Vector(-1.5, -.5, .5)); this->getWeaponManager()->setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0))); this->getWeaponManager()->setSlotPosition(5, Vector(-1.5, -.5, -.5)); this->getWeaponManager()->setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0))); // this->getWeaponManager()->setSlotPosition(6, Vector(-1, 0.0, 0)); this->getWeaponManager()->setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); // // this->getWeaponManager()->setSlotPosition(8, Vector(-2.5, -0.3, -2.0)); // this->getWeaponManager()->setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0))); // // this->getWeaponManager()->setSlotPosition(9, Vector(-2.5, -0.3, 2.0)); // this->getWeaponManager()->setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));: } /** * loads the Settings of a SpaceShip from an XML-element. * @param root the XML-element to load the Spaceship's properties from */ void SpaceShip::loadParams(const TiXmlElement* root) { static_cast(this)->loadParams(root); } /** * adds a weapon to the weapon list of the spaceship * @param weapon to add */ void SpaceShip::addWeapon(Weapon* weapon) { this->getWeaponManager()->addWeapon(weapon); } /** * removes a weapon from the spaceship * @param weapon to remove */ void SpaceShip::removeWeapon(Weapon* weapon) { this->getWeaponManager()->removeWeapon(weapon); } /** * effect that occurs after the SpaceShip is spawned */ void SpaceShip::postSpawn () { //setCollision(new CollisionCluster(1.0, Vector(0,0,0))); } /** * the action occuring if the spaceship left the game */ void SpaceShip::leftWorld () {} WorldEntity* ref = NULL; /** * this function is called, when two entities collide * @param entity: the world entity with whom it collides * * Implement behaviour like damage application or other miscellaneous collision stuff in this function */ void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location) { if (entity->isA(CL_TURRET_POWER_UP) && entity != ref) { this->ADDWEAPON(); ref = entity; } // PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z); } /** * draws the spaceship after transforming it. */ void SpaceShip::draw () const { glMatrixMode(GL_MODELVIEW); glPushMatrix(); /* translate */ glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z); /* rotate */ Vector tmpRot = this->getAbsDir().getSpacialAxis(); glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z ); this->model->draw(); glPopMatrix(); this->getWeaponManager()->draw(); //this->debug(0); } /** * the function called for each passing timeSnap * @param time The timespan passed since last update */ void SpaceShip::tick (float time) { // spaceship controlled movement this->calculateVelocity(time); Vector move = (velocity)*time; //orient the spaceship model in the direction of movement. this->shiftCoor (move); this->getWeaponManager()->tick(time); // weapon system manipulation this->weaponAction(); } /** * calculate the velocity * @param time the timeslice since the last frame */ void SpaceShip::calculateVelocity (float time) { Vector accel(0.0, 0.0, 0.0); //Vector rot(0.0, 0.0, 0.0); //float rotVal = 0.0; /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */ /* calculate the direction in which the craft is heading */ if( this->bUp ) { this->shiftCoor(this->getAbsDirX()); //if(travelSpeed <= 5000) travelSpeed += 10; } if( this->bDown ) { this->shiftCoor(Vector()-this->getAbsDirX()); //if(travelSpeed >= 10) travelSpeed -= 10; } if( this->bLeft /* > -this->getRelCoor().z*2*/) { this->shiftDir(Quaternion(time, Vector(0,1,0))); // accel -= rightDirection; //velocityDir.normalize(); //rot +=Vector(1,0,0); //rotVal -= .4; } if( this->bRight /* > this->getRelCoor().z*2*/) { this->shiftDir(Quaternion(-time, Vector(0,1,0))); // accel += rightDirection; //velocityDir.normalize(); //rot += Vector(1,0,0); //rotVal += .4; } if (this->bAscend ) { this->shiftDir(Quaternion(time, Vector(0,0,1))); // accel += upDirection; //velocityDir.normalize(); //rot += Vector(0,0,1); //rotVal += .4; } if (this->bDescend ) { this->shiftDir(Quaternion(-time, Vector(0,0,1))); // accel -= upDirection; //velocityDir.normalize(); //rot += Vector(0,0,1); //rotVal -= .4; } velocity += accel*(time); //rot.normalize(); //this->setRelDirSoft(Quaternion(rotVal, rot), 5); } /** * weapon manipulation by the player */ void SpaceShip::weaponAction() { if( this->bFire) { this->getWeaponManager()->fire(); } } /** * @todo switch statement ?? */ void SpaceShip::process(const Event &event) { if( event.type == KeyMapper::PEV_UP) this->bUp = event.bPressed; else if( event.type == KeyMapper::PEV_DOWN) this->bDown = event.bPressed; else if( event.type == KeyMapper::PEV_RIGHT) this->bRight= event.bPressed; else if( event.type == KeyMapper::PEV_LEFT) this->bLeft = event.bPressed; else if( event.type == KeyMapper::PEV_FIRE1) this->bFire = event.bPressed; else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed) this->getWeaponManager()->nextWeaponConfig();//if( !event.bPressed) this->bWeaponChange = !this->bWeaponChange; else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed) this->getWeaponManager()->previousWeaponConfig(); else if( event.type == SDLK_PAGEUP) this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0); else if( event.type == SDLK_PAGEDOWN) this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0); } #include "weapons/aiming_turret.h" // FIXME THIS MIGHT BE CONSIDERED EITHER A FEATURE, OR A BUG void SpaceShip::ADDWEAPON() { Weapon* turret = NULL; if ((float)rand()/RAND_MAX < .1) { //if (this->getWeaponManager()->hasFreeSlot(2, WTYPE_TURRET)) { turret = new Turret(); this->getWeaponManager()->addWeapon(turret, 2); this->getWeaponManager()->changeWeaponConfig(2); } } else { //if (this->getWeaponManager()->hasFreeSlot(3)) { turret = new AimingTurret(); this->getWeaponManager()->addWeapon(turret, 3); this->getWeaponManager()->changeWeaponConfig(3); } } if(turret != NULL) { turret->setName("Turret"); turret->setStateDuration(WS_SHOOTING, (float)rand()/RAND_MAX*.5+.1); } }