home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Vehicle.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-22  |  10.0 KB  |  408 lines

  1. #include "Vehicle.h"
  2.  
  3. #include "Game.h"
  4. #include "Renderer.h"
  5. #include "log.h"
  6. #include "intersection.h"
  7. #include "Network.h"
  8. #include "Gui.h"
  9.  
  10. #include "Alleycat.h"
  11. #include "Dragonfly.h"
  12. #include "Sledgehammer.h"
  13. #include "VehicleEffectsParticleClusters.h"
  14.  
  15. #include <math.h>
  16.  
  17. Vehicle::Vehicle(Client* client){
  18.     this->client = client;
  19.  
  20.     vectorCopy3d(client->cs.pos, pos);
  21.     vectorCopy3d(client->cs.dir, dir);
  22.     vectorCopy3d(client->cs.up, up);
  23.     vectorCopy3d(client->cs.vel, vel);    // THINKABOUTME: oder auf 0??
  24.  
  25.     vectorCopy3d(client->cs.vel, vel_inp);
  26. //    vectorInit3d(0.0f, 0.0f, 0.0f, vel_phy);
  27.  
  28.     vectorInit3d(-1.0f, -1.0f, -1.0f, moveAABB.min);
  29.     vectorInit3d(+1.0f, +1.0f, +1.0f, moveAABB.max);
  30.  
  31.     vectorInit3d(-1.0f, -1.0f, -1.0f, hitAABB.min);
  32.     vectorInit3d(+1.0f, +1.0f, +1.0f, hitAABB.max);
  33.  
  34.     boundingSphereRadius = 5.0f;
  35.     
  36.  
  37.     reconstructVectors();
  38.  
  39.     lastProcessMillis = SDL_GetTicks();
  40.     lastMoveMillis = SDL_GetTicks();
  41.     lastRecoveryMillis = SDL_GetTicks();
  42.     lastTakeDamageMillis = 0;
  43.  
  44.     moveSpeed = 1.0f;
  45.     turnSpeed = 1.0f;
  46.  
  47.     maxArmor = 100;
  48.     maxEnergy = 100;
  49.     energyRecovery = 0.0f;
  50.     armor = client->cs.armor;
  51.     energy = client->cs.energy;
  52.  
  53.     for(int i=0;i<4;i++){
  54.         weapons[i] = NULL;
  55.     }
  56. }
  57.  
  58. Vehicle::~Vehicle(){
  59.     for(int i=0;i<4;i++){
  60.         if( weapons[i] != NULL ){
  61.             delete weapons[i];
  62.         }
  63.     }
  64.     
  65. }
  66.  
  67. void Vehicle::processInputArray(inputArray_t inputArray){
  68.     unsigned int currentMillis = SDL_GetTicks();
  69.     
  70.     if( lastProcessMillis >= currentMillis )    // sanity check
  71.         return;
  72.         
  73.     float deltaT = (currentMillis - lastProcessMillis)/1000.0f;
  74.     lastProcessMillis = currentMillis;
  75.  
  76. //    printf("deltaT: %f\n", deltaT);
  77.  
  78.     vectorInit3d(0.0f, 0.0f, 0.0f, vel_inp);
  79.  
  80.     if(inputArray[TURN_UP].pressed){
  81.         turnUp(deltaT);
  82.     }
  83.     if(inputArray[TURN_DOWN].pressed){
  84.         turnDown(deltaT);
  85.     }
  86.     if(inputArray[TURN_LEFT].pressed){
  87.         turnLeft(deltaT);
  88.     }
  89.     if(inputArray[TURN_RIGHT].pressed){
  90.         turnRight(deltaT);
  91.     }
  92.  
  93.     if(inputArray[MOVE_FORWARD].pressed){
  94.         moveForward(deltaT);
  95.     }
  96.     if(inputArray[MOVE_BACKWARD].pressed){
  97.         moveBackward(deltaT);
  98.     }
  99.     if(inputArray[MOVE_LEFT].pressed){
  100.         moveLeft(deltaT);
  101.     }
  102.     if(inputArray[MOVE_RIGHT].pressed){
  103.         moveRight(deltaT);
  104.     }
  105.     if(inputArray[MOVE_UP].pressed){
  106.         moveUp(deltaT);
  107.     }
  108.     if(inputArray[MOVE_DOWN].pressed){
  109.         moveDown(deltaT);
  110.     }
  111.  
  112.     if(inputArray[FIRE_WEAPON_1].pressed && weapons[0] != NULL && weapons[0]->isReadyToFire() ){
  113.         weapons[0]->fire();
  114.     }
  115.     if(inputArray[FIRE_WEAPON_2].pressed && weapons[1] != NULL && weapons[1]->isReadyToFire() ){
  116.         weapons[1]->fire();
  117.     }
  118.     if(inputArray[FIRE_WEAPON_3].pressed && weapons[2] != NULL && weapons[2]->isReadyToFire() ){
  119.         weapons[2]->fire();
  120.     }
  121.     if(inputArray[FIRE_WEAPON_4].pressed && weapons[3] != NULL && weapons[3]->isReadyToFire() ){
  122.         weapons[3]->fire();
  123.     }
  124.  
  125.     vectorsFromAngles();
  126.  
  127.     if( vectorLengthSquared3d(vel_inp) > 0.001f ){
  128.         vectorNormalize3d(vel_inp, vel_inp);
  129.     }else{
  130.         vectorInit3d(0.0f, 0.0f, 0.0f, vel_inp);
  131.     }
  132.  
  133. }
  134.  
  135. void Vehicle::turnLeft(float deltaT){
  136.     yaw = (float)fmod( yaw-(turnSpeed * deltaT), (2*PI));
  137.     if(yaw<0.0f)
  138.         yaw=yaw+(2*PI);
  139. }
  140.  
  141. void Vehicle::turnRight(float deltaT){
  142.     yaw = (float)fmod( yaw+(turnSpeed * deltaT), (2*PI));
  143. }
  144.  
  145. void Vehicle::turnUp(float deltaT){
  146.     pitch -= (turnSpeed * deltaT);
  147.     if(pitch<GAME_OBJECT_MIN_PITCH)
  148.         pitch=GAME_OBJECT_MIN_PITCH;
  149. }
  150.  
  151. void Vehicle::turnDown(float deltaT){
  152.     pitch += (turnSpeed * deltaT);
  153.     if(pitch>GAME_OBJECT_MAX_PITCH)
  154.         pitch=GAME_OBJECT_MAX_PITCH;
  155. }
  156.  
  157. void Vehicle::moveForward(float deltaT){
  158.     vectorMA3d(vel_inp, deltaT*moveSpeed, dir, vel_inp);
  159. }
  160. void Vehicle::moveBackward(float deltaT){
  161.     vectorMA3d(vel_inp, -deltaT*moveSpeed, dir, vel_inp);
  162. }
  163. void Vehicle::moveLeft(float deltaT){
  164.     vectorMA3d(vel_inp, deltaT*moveSpeed, left, vel_inp);
  165. }
  166. void Vehicle::moveRight(float deltaT){
  167.     vectorMA3d(vel_inp, -deltaT*moveSpeed, left, vel_inp);
  168. }
  169. void Vehicle::moveUp(float deltaT){
  170.     vectorMA3d(vel_inp, deltaT*moveSpeed, e2, vel_inp);
  171. }
  172. void Vehicle::moveDown(float deltaT){
  173.     vectorMA3d(vel_inp, -deltaT*moveSpeed, e2, vel_inp);
  174. }
  175.  
  176.  
  177. void Vehicle::move(){
  178. }
  179.  
  180. bool Vehicle::collisionDetection(vec3_t displacement){
  181.     unsigned int i;
  182.     int numIterations = 0;
  183.     vec3_t testPos, normal;
  184.     float t;
  185.     trace_t trace;
  186.     trace.ignoreFlags = 0 | COLLISION_FLAG_BACKFACES | COLLISION_FLAG_WALK_THROUGH /*| COLLISION_FLAG_SUBSEQUENT_HITS*/;
  187.  
  188.     bool positionOk = true;
  189.     do{
  190.         positionOk = true;
  191.  
  192.         vectorAdd3d(pos, displacement, testPos);
  193.  
  194.         // check if pos is save inside arena
  195.         // Game::arena->sptree->traceAABB(pos, testPos, moveAABB.min, moveAABB.max, &trace);
  196.         traceAABB(pos, testPos, moveAABB, &trace);
  197.  
  198.         // TODO: nach dp sortieren!!!
  199.         for(i=0;i<trace.hits.size();i++){
  200. //            printf("trace: %i hits. Processing hit %i\n", trace.hits.size(), i);
  201.  
  202.             if( trace.hits[i].face != NULL ){    // hit a face of the arena
  203.                 Face* f = trace.hits[i].face;
  204.  
  205.                 // find biggest dp
  206.                 float maxDp = vectorDotP3d(displacement, trace.hits[i].face->normal);
  207.                 for(int j=i+1;j<trace.hits.size();j++){
  208.                     if( trace.hits[j].face == NULL )
  209.                         continue;
  210.  
  211.                     float dp = vectorDotP3d(displacement, trace.hits[j].face->normal);
  212.                     if( dp > maxDp && dp < 0.0f ){
  213.                         maxDp = dp;
  214.                         f = trace.hits[j].face;
  215.                     }
  216.                 }
  217.  
  218.                 vectorCopy3d(f->normal, normal);
  219.  
  220.                 // TODO: Push!
  221.  
  222.                 positionOk = false;
  223.             }
  224.             if( trace.hits[i].vehicle != NULL ){    // hit a vehicle
  225.                 if( trace.hits[i].vehicle == this )
  226.                     continue;
  227.  
  228. //                printf("Collided with Vehicle!\n");
  229.                 
  230.                 vectorSub3d(this->pos, trace.hits[i].vehicle->pos, normal);
  231.                 vectorNormalize3d(normal, normal);
  232.                 
  233.                 // push
  234.                 vec3_t u1, u2;
  235.                 float m1 = this->physicsInfo.m;
  236.                 float m2 = trace.hits[i].vehicle->physicsInfo.m;
  237.                 vectorLinCombi3d( (m1-m2)/(m1+m2), this->vel, (2.0f*m2)/(m1+m2), trace.hits[i].vehicle->vel, u1);
  238.                 vectorLinCombi3d( (m2-m1)/(m1+m2), trace.hits[i].vehicle->vel, (2.0f*m1)/(m1+m2), this->vel, u2);
  239.                 vectorCopy3d(u1, this->vel);
  240.                 vectorCopy3d(u2, trace.hits[i].vehicle->vel);
  241.  
  242.                 positionOk = false;
  243.             }
  244.  
  245.             t = vectorDotP3d(normal, displacement);
  246. //            printf("t: %f\n", t);
  247.  
  248.             if( t > 0.0f ){
  249.                 // ignore
  250.             }else if( t < -0.001f ){
  251.                 vectorMA3d(displacement, -t, normal, displacement);
  252.             }else{
  253.                 t = -0.001f;
  254.                 vectorMA3d(displacement, -t, normal, displacement);
  255.             }
  256.  
  257.             break;
  258.         }
  259.  
  260.  
  261.         // count iterations
  262.         numIterations++;
  263.         if(numIterations > 10 ){
  264. //            warn("(in Vehicle::collisionDetection()): Too many iterations. Aborting move.\n\n");
  265.             vectorInit3d(0.0f, 0.0f, 0.0f, displacement);
  266.             return false;
  267.         }
  268.  
  269.     }while( !positionOk );
  270.  
  271.     
  272.     // check if pos is in arenas box
  273.     if(testPos[0]+moveAABB.min[0] < Game::arena->min[0] && displacement[0] < 0.0f
  274.         || testPos[0]+moveAABB.max[0] > Game::arena->max[0] && displacement[0] > 0.0f){
  275.         displacement[0] = 0.0f;
  276.     }
  277.     if(testPos[1]+moveAABB.min[1] < Game::arena->min[1] && displacement[1] < 0.0f
  278.         || testPos[1]+moveAABB.max[1] > Game::arena->max[1] && displacement[1] > 0.0f){
  279.         displacement[1] = 0.0f;
  280.     }
  281.     if(testPos[2]+moveAABB.min[2] < Game::arena->min[2] && displacement[2] < 0.0f
  282.         || testPos[2]+moveAABB.max[2] > Game::arena->max[2] && displacement[2] > 0.0f){
  283.         displacement[2] = 0.0f;
  284.     }
  285.  
  286.  
  287.     return true;
  288. }
  289.  
  290. void Vehicle::calcRecovery(){
  291.     unsigned int currentMillis = SDL_GetTicks();
  292.     float deltaT = (currentMillis - lastRecoveryMillis)/1000.0f;
  293.     lastRecoveryMillis = currentMillis;
  294.     
  295.     energy += deltaT * energyRecovery;
  296.  
  297.     // FIXME: supplypad-rec is done in sp-effect!!
  298. /*
  299.     for(int i=0;i<Game::arena->supplypads.size();i++){
  300.         vec3_t relPos;
  301.         vectorSub3d(pos, Game::arena->supplypads[i].pos, relPos);
  302.         relPos[1] -= 1.0f;
  303.         if( pointIntersectsAABB(relPos, moveAABB.min, moveAABB.max) ){    // standing on supplypad
  304. //            printf("ARGH!\n");
  305.             energy += 10;//deltaT * energyRecovery * 3;
  306.             armor += 10;
  307.         }
  308.     }
  309. */
  310.     if( energy > maxEnergy )
  311.         energy = maxEnergy;
  312.     if( armor > maxArmor )
  313.         armor = maxArmor;
  314.  
  315.     for(int k=0;k<4;k++){
  316.         if( weapons[k] != NULL && weapons[k]->maxEnergy > 0 ){
  317.             weapons[k]->energy += deltaT * 10.0f;
  318.             if( weapons[k]->energy > weapons[k]->maxEnergy ){
  319.                 weapons[k]->energy = weapons[k]->maxEnergy;
  320.             }
  321.         }
  322.     }
  323. }
  324.  
  325. void Vehicle::takeDamage(int amount){
  326.     armor -= amount;
  327.     if( armor < 0 ){
  328.         armor = 0;
  329.     }
  330.  
  331.     // THINKABOUTME: in cs kopieren?
  332.  
  333.     lastTakeDamageMillis = SDL_GetTicks();
  334. }
  335.  
  336. void Vehicle::explode(){
  337.     Renderer::particleSystem.linkParticleCluster( new ExplodingVehicleParticleCluster(this) );
  338. }
  339.  
  340.  
  341.  
  342.  
  343. void Vehicle::addDynamicLightParticleCluster(DynamicLightParticleCluster* dlpc){
  344.     printf("added!\n");
  345. }
  346. void Vehicle::removeDynamicLightParticleCluster(DynamicLightParticleCluster* dlpc){
  347.     printf("removed!\n");
  348. }
  349.  
  350. void Vehicle::render(){
  351.  
  352.     if( Renderer::info.var.renderBoundingBoxes == 1 ){
  353.         Renderer::disableLighting();
  354.  
  355.         glPushMatrix();
  356.         glTranslatef(pos[0], pos[1], pos[2]);
  357.         glColor3f(0.0f, 1.0f, 0.0f);
  358.         Renderer::debug_renderAABB(moveAABB.min, moveAABB.max);
  359.         glColor3f(1.0f, 0.0f, 0.0f);
  360.         Renderer::debug_renderAABB(hitAABB.min, hitAABB.max);
  361.         glPopMatrix();
  362.  
  363.         Renderer::enableLighting();
  364.     }
  365.  
  366.     if( Gui::info.var.hud_draw && Gui::info.var.hud_markTeamMembers
  367.         && Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH 
  368.         && this->client->ci.team == Network::client->ci.team
  369.         ){
  370.  
  371.             vec3_t p;
  372.             vectorMA3d(this->pos, 1.5f, Game::cam.up, p);
  373.             if( Renderer::info.var.useTransparentPolysList ){
  374.                 Renderer::addBillboardToTransparentPolys(p, 1.0f, 1.0f, Gui::hud->teamMarkerShader, SDL_GetTicks());
  375.             }else{
  376.                 Renderer::renderBillboard(p, 1.0f, 1.0f, Gui::hud->teamMarkerShader, SDL_GetTicks());
  377.             }
  378.     }
  379.  
  380. }
  381.  
  382.  
  383.  
  384.  
  385. Vehicle* Vehicle::createVehicleForClient(Client* client){
  386.     Vehicle* ret = NULL;
  387.  
  388.     switch( client->ci.vehicle ){
  389.         case GAME_VEHICLE_DRAGONFLY:
  390.             ret = new Dragonfly(client);
  391.             break;
  392.  
  393.         case GAME_VEHICLE_ALLEYCAT:
  394.             ret = new Alleycat(client);
  395.             break;
  396.  
  397. //        case GAME_VEHICLE_SLEDGEHAMMER:
  398. //            ret = new Sledgehammer(client);
  399. //            break;
  400.  
  401.         default:
  402.             ret = new Dragonfly(client);
  403.             break;
  404.     }
  405.     return ret;
  406. }
  407.  
  408.