Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

Play.cpp

Go to the documentation of this file.
00001 
00007 #include "Play.h"
00008 
00009 /********************************************************************
00010  * Constructor
00011  */
00012 Play::Play() {
00013         unsigned int i;
00014 
00015         for (i=0; i<PLAY_OBJECTS; i++) {
00016                 m_objects[i] = NULL;
00017         }
00018 
00019         m_objLevel = NULL;
00020 }
00021 
00022 /********************************************************************
00023  * Constructor
00024  */
00025 Play::~Play() {
00026         unload();
00027 }
00028 
00029 /********************************************************************
00030  * Load
00031  */
00032 bool Play::load(Application *parent) {
00033 
00034         g_drawConsole = true;
00035 
00036         if (!gne->isRunning())
00037                 return false;
00038 
00039         g_gameInfo.gameState = GAME_STATE_WAITING;
00040 
00041         // --- THIS WONT BE NEEDED -----
00042         //g_myPlayerID = 0;
00043         //g_players[g_myPlayerID].name;
00044         //strcpy(g_players[g_myPlayerID].name, "Death Bringer");
00045 
00067         //---------
00068 
00069         //g_players[g_myPlayerID].life = 10.0f;
00070 
00071         //setSpawnPlayer(g_myPlayerID);
00072         
00073         
00074         if (parent != NULL)
00075                 m_parent = parent;
00076 
00077         if (!loadTextures())
00078                 return false;
00079 
00080         if (!loadObjects())
00081                 return false;
00082 
00083         loadSounds();
00084 
00085         g_showFPS = false;
00086 
00087         //m_parent->camera.setPosition(Vec3(11.0f, 13.0f, 18.0f));
00088         //m_parent->camera.setPitch(55.0f);
00089         //m_parent->camera.setHeading(90.0f);
00090 
00091         // "bot" player
00092         //strcpy(g_players[1].name, "Bot1");
00093         //strcpy(g_players[2].name, "Bot2");
00094         //setSpawnPlayer(1);
00095         //setSpawnPlayer(2);
00096 
00097 
00098         // reset extras
00099         for (unsigned int i=0; i<PLAY_EXTRAS_SIMULTANEOUS; i++) {
00100                 m_extras[i].type = PLAY_EXTRAS_NONE;
00101         }
00102 
00103         //if (m_parent->renderer->lockFlags & LF_SHADING) {
00104         //      if ((m_shader = m_parent->renderer->addShader("data\\shaders\\specular.cg")) == SHADER_NONE) return false;
00105         //}
00106 
00107         this->setPlayerCam(g_myPlayerID);
00108 
00109 
00110         if (!gne->isRunning()) {
00111                 console.addEx(Vec3(1.0f, 1.0f, 1.0f), "Press ENTER to start console/chat");
00112                 console.addEx(Vec3(1.0f, 0.0f, 1.0f), "/server - starts new server");
00113                 console.addEx(Vec3(1.0f, 1.0f, 0.0f), "/connect IP - connects to server");
00114         }
00115 
00116         // Disable all old lights
00117         for (i=0; i<GL_MAX_LIGHTS; i++) {
00118                 glDisable(GL_LIGHT0+i);
00119         }
00120 
00121         // notify network I'm ready
00122         g_players[g_myPlayerID].state = PLAYER_STATE_READY;
00123         gne->setPlayerState(g_myPlayerID, PLAYER_STATE_READY);
00124 
00125         LOG_SUCCESS(("Play game loaded"));
00126         m_loaded = true;
00127         return true;
00128 }
00129 
00130 /********************************************************************
00131  * Load textures
00132  */
00133 bool Play::loadTextures() {
00134         
00135         unsigned int i;
00136 
00137         if ((m_textures[PLAY_TEX_SKIN] = 
00138                 m_parent->renderer->addTexture("data\\textures\\skins\\arrow.bmp")) == TEXTURE_NONE) return false;
00139 
00140         if ((m_textures[PLAY_TEX_GRENADE] = 
00141                 m_parent->renderer->addTexture("data\\textures\\planets\\earth.bmp")) == TEXTURE_NONE) return false;
00142 
00143         if ((m_textures[PLAY_TEX_PARTICLE] = 
00144                 m_parent->renderer->addTexture("data\\textures\\particles\\flare.bmp")) == TEXTURE_NONE) return false;
00145 
00146         if ((m_textures[PLAY_TEX_SHADOW] = 
00147                 m_parent->renderer->addTexture("data\\textures\\common\\shadow.bmp")) == TEXTURE_NONE) return false;
00148 
00149         if ((m_textures[PLAY_TEX_SPAWN_SPHERE] = 
00150                 m_parent->renderer->addTexture("data\\textures\\common\\spawn_sphere.bmp")) == TEXTURE_NONE) return false;
00151 
00152         if ((m_textures[PLAY_TEX_MODEL_0] = 
00153                 m_parent->renderer->addTexture("data\\textures\\avatars\\robot1.bmp")) == TEXTURE_NONE) return false;
00154 
00155         if ((m_textures[PLAY_TEX_LIFEBAR_FRAME] = 
00156                 m_parent->renderer->addTexture("data\\textures\\play\\lifebar_frame.bmp")) == TEXTURE_NONE) return false;
00157 
00158         if ((m_textures[PLAY_TEX_LIFEBAR_BG] = 
00159                 m_parent->renderer->addTexture("data\\textures\\play\\lifebar_bg.bmp")) == TEXTURE_NONE) return false;
00160 
00161         if ((m_textures[PLAY_TEX_LIFEBAR_GLOW] = 
00162                 m_parent->renderer->addTexture("data\\textures\\play\\lifebar_glow.bmp")) == TEXTURE_NONE) return false;
00163 
00164         if ((m_textures[PLAY_TEX_EXTRAS_OTHER] = 
00165                 m_parent->renderer->addTexture("data\\textures\\common\\extras_other.bmp")) == TEXTURE_NONE) return false;
00166 
00167         if ((m_textures[PLAY_TEX_GAME_OVER] = 
00168                 m_parent->renderer->addTexture("data\\textures\\play\\game_over.bmp")) == TEXTURE_NONE) return false;
00169 
00170 
00171         // Player skins
00172         for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00181                 if ((g_players[i].textureID = 
00182                         m_parent->renderer->addTexture(g_allModels[g_players[i].model].skin)) == TEXTURE_NONE) return false;    
00183         }
00184 
00185 
00186         return true;
00187 }
00188 
00189 /********************************************************************
00190  * Load objects
00191  */
00192 bool Play::loadObjects() {
00193         //--------------------
00194         // Level object
00195         //--------------------
00196                 //if (!Level::load(m_lvl,"data\\lvls\\crystal1.lvl")) {
00197                 //if (!Level::load(m_lvl,"data\\lvls\\radioactive1.lvl")) {
00198                 //if (!Level::load(m_lvl,"data\\lvls\\lvl1.lvl")) {
00199         char file[256] = {0};
00200         //LOG_MISC(("Galaxy:%d, Level:%d",g_gameInfo.currLvl[0],g_gameInfo.currLvl[1]));
00201         sprintf(file, "data\\lvls\\%s",g_galaxies[g_gameInfo.currLvl[0]].lvls[g_gameInfo.currLvl[1]].file);
00202         //LOG_MISC(("Level file:%s",file));
00203         //console.addEx(Vec3(1.0f, 1.0f, 1.0f), "Level: %s", file);
00204 
00205         if (!Level::load(m_lvl,file)) {
00206                 return false;
00207         }
00208 
00209         m_objLevel = new ObjLevel(m_lvl, m_parent->renderer);
00210         if (!m_objLevel->load()) return false;
00211         m_objLevel->createVertexBuffer();
00212         //--------------------
00213         //--------------------
00214 
00215         m_objects[PLAY_OBJ_GRENADE] = new Sphere(0.0f, 0.0f, 0.0f, 0.05f, 4);
00216         m_objects[PLAY_OBJ_SPHERE] = new Sphere(0.0f, 0.0f, 0.0f, 0.65f, 22);
00217 
00218 
00219         // models
00220         for (int i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00221                 if (!g_models[i].loadFromAsciiFile("data\\models\\", g_allModels[g_players[i].model].file))
00222                         return false;
00223                 //if (!g_models[i].loadFromAsciiFile("data\\models\\", "robot.txt"))
00224                 //      return false;
00225         }
00226 
00227         return true;
00228 }
00229 
00230 /********************************************************************
00231  * Load sounds
00232  */
00233 bool Play::loadSounds() {
00234         m_sounds[PLAY_SOUND_GRENADE].load("data\\sounds\\weapon\\Grenade3.wav");
00235         m_sounds[PLAY_SOUND_SPAWN].load("data\\sounds\\spawn.wav");
00236         m_sounds[PLAY_SOUND_GUN].load("data\\sounds\\weapon\\gun.wav");
00237         m_sounds[PLAY_SOUND_DEATH].load("data\\sounds\\death.wav");
00238         m_sounds[PLAY_SOUND_GUN_HIT].load("data\\sounds\\weapon\\gun_hit.wav");
00239         m_sounds[PLAY_SOUND_DROWN].load("data\\sounds\\drown.wav");
00240 
00241         m_sounds[PLAY_SOUND_EXTRAS_LIFE].load("data\\sounds\\extras\\life.wav");
00242         m_sounds[PLAY_SOUND_EXTRAS_AMMO].load("data\\sounds\\extras\\ammo.wav");
00243         m_sounds[PLAY_SOUND_EXTRAS_SLOW].load("data\\sounds\\extras\\slow.wav");
00244         m_sounds[PLAY_SOUND_EXTRAS_SHAKE].load("data\\sounds\\extras\\shake.wav");
00245         m_sounds[PLAY_SOUND_EXTRAS_FAST].load("data\\sounds\\extras\\fast.wav");
00246         m_sounds[PLAY_SOUND_EXTRAS_FLIPVIEW].load("data\\sounds\\extras\\flipview.wav");
00247         m_sounds[PLAY_SOUND_EXTRAS_INVISIBLE].load("data\\sounds\\extras\\invisible.wav");
00248         m_sounds[PLAY_SOUND_EXTRAS_IMMORTAL].load("data\\sounds\\extras\\immortal.wav");
00249 
00250         m_music.load("data\\music\\exp.xm");
00251         m_music.play();
00252 
00253         return true;
00254 }
00255 
00256 /********************************************************************
00257  * Unload
00258  */
00259 bool Play::unload() {
00260         if (!m_loaded)
00261                 return false;
00262 
00263         unsigned int i;
00264 
00265         for (i=0; i<PLAY_SOUNDS; i++) {
00266                 m_sounds[i].unload();
00267         }
00268 
00269         m_music.stop();
00270         m_music.unload();
00271 
00272         for (i=0; i<PLAY_OBJECTS; i++) {
00273                 if (m_objects[i]) {
00274                         m_objects[i]->clearVertexBuffer();
00275                         delete m_objects[i];
00276                 }
00277                 m_objects[i] = NULL;
00278         }
00279 
00280         Level::unload(m_lvl);
00281 
00282         if (m_objLevel) delete m_objLevel;
00283         m_objLevel = NULL;
00284 
00285         for (i=0; i<PLAY_TEXTURES; i++) {
00286                 m_parent->renderer->deleteTexture(m_textures[i]);
00287         }
00288 
00289         // Player skins
00290         for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00291                 if (strcmp(g_players[i].skin, "") != 0 && g_players[i].textureID != TEXTURE_NONE) {
00292                         m_parent->renderer->deleteTexture(g_players[i].textureID);
00293                 }
00294         }
00295 
00296 
00297         //g_models[0].clear();
00298         //g_models[1].clear();
00299         //g_models[2].clear();
00300 
00301         // models
00302         for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00303                 g_models[i].clear();
00304         }
00305 
00306         //if (m_parent->renderer->lockFlags & LF_SHADING) {
00307         //      m_parent->renderer->deleteShader(m_shader);
00308         //}
00309 
00310         LOG_SUCCESS(("Play game unloaded"));
00311         m_loaded = false;
00312         return true;
00313 }
00314 
00315 /********************************************************************
00316  * Update
00317  */
00318 bool Play::update() {
00319         if (!m_loaded)
00320                 return false;
00321 
00322         unsigned int i, n;
00323 
00324         if (g_gameInfo.gameState == GAME_STATE_GAME_OVER) {
00325                 if (g_time > m_timeEnd + 1500.0f) {
00326                         g_selectedScene = SCENE_SCORES;
00327                 }
00328                 return true;
00329         }
00330 
00331         handleKeys();
00332 
00333         //======= REMOVE ==========
00334         //this->bot(1);
00335         //this->bot(2);
00336 
00337 
00338         this->networkLoop();
00339         this->serverLoop();
00340 
00341         //if (g_gameInfo.gameState != PLAYER_STATE_RUNNING)
00342         //      return true;
00343 
00344         //-----------------------------------------------------------------#
00345         // Main player loop (move all players)
00346         //-----------------------------------------------------------------#
00347         float rotSpeed = g_frameTime*0.3f;
00348         bool rotationChanged = false;
00349 
00350         float maxSpeed;
00351         bool moveChanged = false;
00352         float friction = (m_lvl.friction*0.00005f)*g_frameTime*0.3f;
00353         float speed;
00354         Vec3 pos;
00355         SPlayer *player;
00356 
00357         for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00358                 if (g_players[i].state != PLAYER_STATE_USER)
00359                         continue;
00360 
00361                 player = &g_players[i];
00362 
00363                 maxSpeed = 0.004f + player->extras[PLAY_EXTRAS_FAST]*0.002f - player->extras[PLAY_EXTRAS_SLOW]*0.002f;
00364                 if (maxSpeed < 0.001f) maxSpeed = 0.001f;
00365 
00366                 moveChanged = false;
00367 
00368                 //-------------------------------
00369                 // Rotation
00370                 //-------------------------------
00371                 switch (player->rotation) {
00372                         case PLAYER_ROTATION_NONE:                                                      // no rotation
00373                                 break;
00374 
00375                         case PLAYER_ROTATION_LEFT:                                                      // rotation left
00376                                 player->angle += rotSpeed;
00377                                 rotationChanged = true;
00378                                 break;
00379 
00380                         case PLAYER_ROTATION_RIGHT:                                                     // rotation right
00381                                 player->angle -= rotSpeed;
00382                                 rotationChanged = true;
00383                                 break;
00384 
00385                         default:
00386                                 break;
00387                 }
00388 
00389                 //if (rotationChanged) {                                                                        // update angle and direction if needed
00390                         float angle = player->angle*PIdiv180;
00391                         float x = sinf(angle);
00392                         float z = cosf(angle);
00393                         player->dir = Vec3(x, 0.0f, z);
00394                         player->dir = player->dir.normalize();
00395                 //}
00396 
00397                 //-------------------------------
00398                 // Moving
00399                 //-------------------------------
00400                 switch (player->moving) {
00401                         case PLAYER_MOVING_NONE:                                                        // no moving (slow down)
00402                                 if (player->speed > 0.0f) {
00403                                         player->speed -= friction;
00404 
00405                                         if (player->speed < 0.0f) {
00406                                                 player->speed = 0.0f;
00407                                         }
00408                                         else {
00409                                                 moveChanged = true;
00410                                         }
00411                                 }
00412                                 break;
00413 
00414                         case PLAYER_MOVING_FORWARD:                                                     // move forward
00415                                 player->speed = maxSpeed;
00416                                 player->moveVal = -1;
00417                                 moveChanged = true;
00418                                 break;
00419 
00420                         case PLAYER_MOVING_BACKWARD:
00421                                 player->speed = maxSpeed;                                               // move backward
00422                                 player->moveVal = 1;
00423                                 moveChanged = true;
00424                                 break;
00425                 }
00426 
00427                 if (moveChanged) {                                                                              // update position
00428                         pos = player->pos;
00429                         speed = player->speed*player->moveVal*g_frameTime;
00430 
00431                                 // x dir                                                                                // Collission detection
00432                                 pos.x = player->pos.x + player->dir.x * speed;
00433                                 if (!m_objLevel->collission(pos, 0.25f))
00434                                         player->pos.x = pos.x;
00435 
00436                                 // z dir
00437                                 pos = player->pos;
00438                                 pos.z = player->pos.z + player->dir.z * speed;
00439                                 if (!m_objLevel->collission(pos, 0.25f))
00440                                         player->pos.z = pos.z;
00441 
00442                                 if (i == g_myPlayerID) {
00443                                         if (m_objLevel->isWater(player->pos)) {                 // drown
00444                                                 player->state = PLAYER_STATE_INVISIBLE;
00445                                                 gne->setPlayerAction(i, PLAY_ACTION_PLAYER_DROWN);
00446                                         }
00447                                 }
00448 
00449                                 player->pos.y = 0.0f;
00450 
00451                         g_models[i].advanceAnimation(g_frameTime*0.035f);
00452                 }
00453 
00454                 //-------------------------------
00455                 // Server stuff (extras)
00456                 //-------------------------------
00457                 if (gne->isServer()) {
00458                         float dist;
00459                         for (n=0; n<PLAY_EXTRAS_SIMULTANEOUS; n++) {
00460                                 if (m_extras[n].type == PLAY_EXTRAS_NONE)
00461                                         continue;
00462 
00463                                 dist = (player->pos - m_extras[n].pos).length();
00464 
00465                                 if (dist <= 0.40f) {
00466                                         gne->dealExtras(m_extras[n].type, m_extras[n].pos.x, m_extras[n].pos.z, 0);     // remove extras
00467                                         gne->setPlayerExtras(i, m_extras[n].type, 1);
00468                                         m_extras[n].type = PLAY_EXTRAS_NONE;
00469                                 }
00470                         }
00471 
00472                         for (n=0; n<PLAY_EXTRAS; n++) {
00473                                 if (player->extras[n] != 0 && player->timeExtras[n] <= g_time) {        // remove player extras
00474                                         //console.addEx(Vec3(0.0f, 0.0f, 1.0f), "Player %d extras type %d remove requested", i, n);
00475                                         gne->setPlayerExtras(i, n, 0);
00476                                 }
00477                         }
00478                 
00479                 }
00480 
00481         }
00482 
00483         this->setPlayerCam(g_myPlayerID);
00484 
00485         return true;
00486 }
00487 
00488 /********************************************************************
00489  * Handle keys
00490  */
00491 void Play::handleKeys() {
00492         static float lastGrenade = 0.0f;
00493         static float lastProjectile = 0.0f;
00494         static int gunPos = 0;
00495 
00496         static int lastRotation = 0;
00497         static int lastMove = 0;
00498         
00499         static float lastTime = 0.0f;
00500 
00501         bool rotationChanged = false;
00502         bool moveChanged = false;
00503 
00504         SPlayer *player = &g_players[g_myPlayerID];
00505 
00506         if (player->state != PLAYER_STATE_USER)
00507                 return;
00508 
00509         if (g_time - lastTime < 75.0f)                                                          // Keep player update rate down!
00510                 return;
00511 
00512         lastTime = g_time;
00513 
00514         if (m_parent->keys['O']) {
00515                 gne->setPlayerExtras(PLAY_NET_GAME_OVER, 0, 0);
00516         }
00517 
00575         //if (m_parent->keys['O']) {
00576         //      Weapon::set(g_players[g_myPlayerID].weapon, WEAPON_ROCKET);
00577         //      m_parent->keys['O'] = false;
00578         //}
00579 
00580         //-----------------------------------------------------------------#
00581         // Rotation
00582         //-----------------------------------------------------------------#
00583 
00584         int rotation = 0;
00585 
00586         if (m_parent->keys[VK_LEFT])
00587                 rotation--;
00588 
00589         if (m_parent->keys[VK_RIGHT])
00590                 rotation++;
00591 
00592         if (rotation != lastRotation) {
00593                 if (rotation == -1)
00594                         player->rotation = PLAYER_ROTATION_LEFT;
00595                 else if (rotation == 1)
00596                         player->rotation = PLAYER_ROTATION_RIGHT;
00597                 else
00598                         player->rotation = PLAYER_ROTATION_NONE;
00599 
00600 
00601                 lastRotation = rotation;
00602                 rotationChanged = true;
00603         }
00604 
00605 
00606         //-----------------------------------------------------------------#
00607         // Moving
00608         //-----------------------------------------------------------------#
00609         int move = 0;
00610 
00611         if (m_parent->keys[VK_UP])
00612                 move++;
00613 
00614         if (m_parent->keys[VK_DOWN])
00615                 move--;
00616 
00617         if (move != lastMove) {
00618                 if (move == 1)
00619                         player->moving = PLAYER_MOVING_FORWARD;
00620                 else if (move == -1)
00621                         player->moving = PLAYER_MOVING_BACKWARD;
00622                 else
00623                         player->moving = PLAYER_MOVING_NONE;
00624 
00625                 lastMove = move;
00626                 moveChanged = true;
00627         }
00628 
00629 
00630         if (rotationChanged || moveChanged) {                                   // send move, rotation, position and angle to network
00631                 //if (g_time - lastTime > 50.0f ||
00632                 //              player->rotation == PLAYER_ROTATION_NONE ||
00633                 //              player->moving == PLAYER_MOVING_NONE) {
00634 
00635                 //      lastTime = g_time;
00636                         gne->setPlayerPos(g_myPlayerID, player->rotation, player->moving, player->pos.x, player->pos.z, player->angle);
00637                 //}
00638         }
00639 
00640         float angle = -player->angle*PIdiv180;
00641         float cosA = cos(angle);
00642         float sinA = sin(angle);
00643 
00644         if (m_parent->keys['Z']) {                                                                                      // throw grenade!
00645                 if (g_time - lastGrenade > 500.0f) {
00646                         Vec3 gunVec = Vec3(0.0f, 0.25f, 0.0f);
00647                         if (g_models[g_myPlayerID].numGuns > 0) {
00648                                 if (++gunPos >= g_models[g_myPlayerID].numGuns) gunPos = 0;
00649                                 
00650                                 gunVec = g_models[g_myPlayerID].guns[gunPos];
00651 
00652                                 Vec3 tmp = gunVec;
00653                                 gunVec.x = tmp.x*cosA-tmp.z*sinA;
00654                                 gunVec.z = tmp.x*sinA+tmp.z*cosA;
00655                         }
00656 
00657                         Vec3 pos = player->pos + gunVec;
00658                         Vec3 dir = -(player->dir*0.015f - player->dir*player->speed*2.0f*player->moveVal) * 150.0f + Vec3(0.0f, 6.0f, 0.0f);
00659 
00660                         gne->sendAttack(g_myPlayerID, WEAPON_GRENADE, pos.x, pos.y, pos.z, dir.x, dir.y, dir.z);
00661 
00662                         lastGrenade = g_time;
00663                         throwGrenade(g_myPlayerID, pos, dir, 3.0f, 1.0f);
00664                         //m_parent->keys['Z'] = false;
00665                 }
00666         }
00667 
00668         if (m_parent->keys['X']) {                                                                                      // fire projectile
00669                 if (g_time - lastProjectile > player->weapon.reload) {
00670                         Vec3 gunVec = Vec3(0.0f, 0.25f, 0.0f);
00671                         if (g_models[g_myPlayerID].numGuns > 0) {
00672                                 if (++gunPos >= g_models[g_myPlayerID].numGuns) gunPos = 0;
00673                                 
00674                                 gunVec = g_models[g_myPlayerID].guns[gunPos];
00675 
00676                                 Vec3 tmp = gunVec;
00677                                 gunVec.x = tmp.x*cosA-tmp.z*sinA;
00678                                 gunVec.z = tmp.x*sinA+tmp.z*cosA;
00679                         }
00680 
00681                         m_sounds[PLAY_SOUND_GUN].play(125);
00682 
00683                         Vec3 pos = player->pos + gunVec;
00684                         Vec3 dir = -player->dir*(150.0f*player->speed+1.0f)*6.0f*player->weapon.speed;
00685 
00686                         gne->sendAttack(g_myPlayerID, player->weapon.type, pos.x, pos.y, pos.z, dir.x, dir.y, dir.z);
00687 
00688                         lastProjectile = g_time;
00689                         fireProjectile(g_myPlayerID, pos, dir, player->weapon.power);
00690                         //m_parent->keys['X'] = false;
00691                 }
00692         }
00693 
00694 }
00695 
00696 /********************************************************************
00697  * Draw frame
00698  */
00699 bool Play::drawFrame() {
00700         if (!m_loaded)
00701                 return false;
00702 
00703         unsigned int i = 0;
00704 
00705         if (!gne->isRunning())
00706                 return true;
00707 
00708         if (g_gameInfo.gameState == GAME_STATE_WAITING) {
00709                 m_parent->defaultFont->startTextMode();
00710                 m_parent->defaultFont->setColor(0.0f, 0.0f, 1.0f, 1.0f);
00711                 m_parent->defaultFont->print((float)g_width/2.0f - 75.0f, (float)g_height/2.0f, "WAITING FOR PLAYERS...");
00712                 m_parent->defaultFont->endTextMode();
00713                 return true;
00714         }
00715 
00716         m_parent->camera.setPrespective(g_frameTime*0.001f);
00717         m_parent->camera.updateFrustum();
00718 
00719         for (i=0; i<m_lvl.numLights; i++) {
00720                 glLightfv(GL_LIGHT0+i, GL_AMBIENT, m_lvl.lights[i].ambient);
00721                 glLightfv(GL_LIGHT0+i, GL_DIFFUSE, m_lvl.lights[i].color);
00722                 glLightfv(GL_LIGHT0+i, GL_POSITION,Vec4(m_lvl.lights[i].pos, 1.0f));
00723                 glLightf(GL_LIGHT0+i, GL_CONSTANT_ATTENUATION, m_lvl.lights[i].attenuation.x);
00724                 glLightf(GL_LIGHT0+i, GL_LINEAR_ATTENUATION, m_lvl.lights[i].attenuation.y);
00725                 glLightf(GL_LIGHT0+i, GL_QUADRATIC_ATTENUATION, m_lvl.lights[i].attenuation.z);
00726                 glEnable(GL_LIGHT0+i);
00727         }
00728 
00729         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00730 
00731         glEnable(GL_LIGHTING);
00732         glStencilMask(0xF);
00733 
00734         //------------------------------------------------------------
00735         // USE STENCIL BUFFER - (Two environment renders needed. Using z-pass algorithm)
00736         //------------------------------------------------------------
00737         if (g_stencilBuffer) {
00738 
00739                 glDisable(GL_LIGHT0);
00740 
00741                         m_objLevel->drawFloor();
00742                         m_objLevel->drawWalls();
00743                         m_objLevel->drawWater();
00744 
00745                         //m_parent->renderer->setTextures(m_textures[PLAY_TEX_GRENADE]);
00746                         //m_parent->renderer->apply();
00747                         m_objLevel->drawObjects();
00748 
00749                         //drawPlayer(&player);
00750                         drawPlayers();
00751 
00752                 glEnable(GL_LIGHT0);
00753 
00754                 glEnable(GL_STENCIL_TEST);
00755                 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT);
00756                 {
00757 
00758                         m_parent->renderer->setMask(NONE);
00759                         m_parent->renderer->apply();
00760 
00761                         glEnable(GL_CULL_FACE);
00762 
00763                         glStencilFunc(GL_ALWAYS, 0, ~0);
00764 
00765                         glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
00766                         glCullFace(GL_FRONT);
00767                         m_objLevel->drawShadow();
00768 
00769                         glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
00770                         glCullFace(GL_BACK);
00771                         m_objLevel->drawShadow();
00772 
00773                         glDisable(GL_CULL_FACE);
00774                 }
00775                 glPopAttrib();
00776 
00777                 m_parent->renderer->apply();
00778 
00779                 glEnable(GL_STENCIL_TEST);
00780                 glStencilFunc(GL_EQUAL, 0, ~0);
00781                 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
00782 
00783                 m_objLevel->drawFloor();
00784                 m_objLevel->drawWalls();
00785                 m_objLevel->drawWater();
00786 
00787                 //m_parent->renderer->setTextures(m_textures[PLAY_TEX_GRENADE]);
00788                 //m_parent->renderer->apply();
00789                 m_objLevel->drawObjects();
00790 
00791                 //drawPlayer(&player);
00792                 drawPlayers();
00793 
00794                 glDisable(GL_STENCIL_TEST);
00795 
00796         }
00797         //------------------------------------------------------------
00798         // Just render :) (no shadows)
00799         //------------------------------------------------------------
00800         else {
00801 
00802                 glEnable(GL_LIGHTING);
00803 
00804                 m_objLevel->drawFloor();
00805                 m_objLevel->drawWalls();
00806                 m_objLevel->drawWater();
00807 
00808                 //m_parent->renderer->setTextures(m_textures[PLAY_TEX_GRENADE]);
00809                 //m_parent->renderer->apply();
00810                 m_objLevel->drawObjects();
00811 
00812                 //drawPlayer(&g_players[m_selfID]);
00813                 drawPlayers();
00814         }
00815 
00816         m_objLevel->drawWaterSurface();
00817         
00818         glDisable(GL_LIGHTING);
00819 
00820         drawGrenades();
00821         drawProjectiles();
00822 
00823         drawExtras();
00824 
00825         drawExplosions();
00826         drawParticleSystems();
00827 
00828 
00829         //------------------------------------------------------------
00830         // User stats, info and stuff
00831         //------------------------------------------------------------
00832         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00833         m_parent->defaultFont->startTextMode();
00834         //m_parent->defaultFont->setColor(1.0f, 1.0f, 1.0f, 1.0f);
00835         //m_parent->defaultFont->print(20.0f, 70.0f, "g_myPlayerID: %d", g_myPlayerID);
00836         //m_parent->defaultFont->print(20.0f, 90.0f, "networkID: %d", gne->getPlayerIdSelf());  // GUI (life etc)
00837 
00838         float timeLeft = (m_timeEnd - g_time)*0.001f;
00839         int timeLeftMin = (int)(timeLeft/60.0f);
00840         int timeLeftSec = (int)(timeLeft - timeLeftMin*60);
00841         m_parent->defaultFont->setColor(1.0f, 1.0f, 1.0f, 1.0f);
00842         m_parent->defaultFont->print((float)g_width/2.0f - 30.0f, 50.0f, "%d:%s%d", timeLeftMin, (timeLeftSec < 10 ? "0" : ""),timeLeftSec);
00843 
00844         if (g_players[g_myPlayerID].state == PLAYER_STATE_USER) {
00845 
00846                 //drawAvatar(PLAY_TEX_MODEL_0, true);
00847                 //drawAvatar(PLAY_TEX_MODEL_0);
00848                 //drawAvatar(PLAY_TEX_MODEL_0);
00849 
00850                 //m_parent->defaultFont->setColor(1.0f, 1.0f, 1.0f, 1.0f);
00851                 //m_parent->defaultFont->print(20.0f, (g_fullscreen ? 30.0f : 50.0f), "Pitch: %f", m_parent->camera.m_pitchDegrees);
00852                 //m_parent->defaultFont->print(20.0f, (g_fullscreen ? 50.0f : 70.0f), "Heading: %f", m_parent->camera.m_headingDegrees);
00853 
00854                 //m_parent->defaultFont->print(20.0f, (g_fullscreen ? 30.0f : 50.0f), "Life: %f", g_players[g_myPlayerID].life);
00855 
00856                 //m_parent->defaultFont->print(20.0f, 110.0f, "X: %f, Z: %f", g_players[g_myPlayerID].pos.x, g_players[g_myPlayerID].pos.z);
00857 
00858                 this->drawLifebar();
00859 
00860         }
00861 
00862         //------------------------------------------------------------
00863         // Game Over
00864         //------------------------------------------------------------
00865         if (g_gameInfo.gameState == GAME_STATE_GAME_OVER) {
00866                 float x = (float)g_width/2.0f;
00867                 float y = (float)g_height/2.0f;
00868                 float scale = ((m_timeEnd-g_time)/1500.0f);
00869                 float w = 300.0f*scale;
00870                 float h = w/2;
00871 
00872                 float c = 1.0f+scale;
00873                 glColor4f(c, c, c, c);
00874 
00875                 m_parent->renderer->setMask(COLOR);
00876                 m_parent->renderer->setTextures(m_textures[PLAY_TEX_GAME_OVER]);
00877                 m_parent->renderer->setBlending(ONE, ONE);
00878                 m_parent->renderer->apply();
00879 
00880                 glBegin(GL_QUADS);
00881                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
00882                         glVertex2f(x-w, y-h);
00883 
00884                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
00885                         glVertex2f(x-w, y+h);
00886 
00887                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
00888                         glVertex2f(x+w, y+h);
00889 
00890                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
00891                         glVertex2f(x+w, y-h);
00892                 glEnd();
00893         }
00894 
00895         m_parent->defaultFont->endTextMode();
00896 
00897         //------------------------------------------------------------
00898         // Score board
00899         //------------------------------------------------------------
00900         if (m_parent->keys[VK_TAB]) {
00901                 m_parent->defaultFont->startTextMode();
00902 
00903                 int x = g_width/2.0f - 200.0f;
00904                 int y = 140.0f;
00905 
00906                 m_parent->defaultFont->setColor(1.0f, 1.0f, 1.0f, 1.0f);
00907                 m_parent->defaultFont->print(x, y, "[Name]               [Frags]      [Kills]      [Deaths]");
00908 
00909                 y += 25.0f;
00910                 
00911                 SPlayer *player;
00912                 for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00913                         if (g_players[i].state != PLAYER_STATE_OFFLINE) {
00914                                 player = &g_players[i];
00915 
00916                                 m_parent->defaultFont->setColor(1.0f, 1.0f, 0.0f, 1.0f);
00917                                 m_parent->defaultFont->print(x, y, "%s", player->name);
00918 
00919                                 m_parent->defaultFont->setColor(0.0f, 0.0f, 1.0f, 1.0f);
00920                                 m_parent->defaultFont->print(x+22.0f*7.65f, y, "[%d]", player->frags);
00921 
00922                                 m_parent->defaultFont->setColor(0.0f, 1.0f, 0.0f, 1.0f);
00923                                 m_parent->defaultFont->print(x+35.5f*7.65f, y, "[%d]", player->kills);
00924 
00925                                 m_parent->defaultFont->setColor(1.0f, 0.0f, 0.0f, 1.0f);
00926                                 m_parent->defaultFont->print(x+49.25f*7.65f, y, "[%d]", player->deaths);
00927 
00928                                 y += 25.0f;
00929                         }
00930                 }
00931 
00932                 m_parent->defaultFont->endTextMode();
00933         }
00934 
00935 
00936         m_parent->renderer->apply();    // needed for what?
00937 
00938         return true;
00939 }
00940 
00941 /********************************************************************
00942  * Throw grenade
00943  */
00944 void Play::throwGrenade(int playerID, Vec3 pos, Vec3 vel, float life, float strength) {
00945         for (unsigned int i=0; i<MAX_GRANADES; i++) {
00946                 if (!m_granades[i].isAlive()) {
00947                         m_granades[i].create(pos, vel, life, strength);
00948                         m_granades[i].setPlayerID(playerID);
00949                         return;
00950                 }
00951         }
00952 }
00953 
00954 /********************************************************************
00955  * Fire projectile
00956  */
00957 void Play::fireProjectile(int playerID, Vec3 pos, Vec3 vel, float strength) {
00958         for (unsigned int i=0; i<MAX_PROJECTILES; i++) {
00959                 if (!m_projectiles[i].isAlive()) {
00960                         m_projectiles[i].create(pos, vel, strength);
00961                         m_projectiles[i].setPlayerID(playerID);
00962                         return;
00963                 }
00964         }
00965 }
00966 
00967 /********************************************************************
00968  * Create explosion
00969  */
00970 void Play::createExplosion(Vec3 pos, float power, bool sphere) {
00971         for (unsigned int i=0; i<MAX_EXPLOSIONS; i++) {
00972                 if (!m_explosions[i].isAlive()) {
00973                         m_explosions[i].explode(pos, power, sphere);
00974                         return;
00975                 }
00976         }
00977 }
00978 
00979 /********************************************************************
00980  * Draw Grenades
00981  */
00982 void Play::drawGrenades() {
00983         m_parent->renderer->setTextures(m_textures[PLAY_TEX_GRENADE]);
00984         m_parent->renderer->apply();
00985         Vec3 pos;
00986         float dTime = g_frameTime*0.001f;
00987         for (unsigned int i=0; i<MAX_GRANADES; i++) {
00988                 if (m_granades[i].isAlive()) {
00989                         // wierd? :) (if update returns true, the granade explodes)
00990                         if (m_granades[i].update(dTime, m_objLevel)) {
00991                                 pos = m_granades[i].getPos();
00992                                 grenadeExplode(m_granades[i].getPlayerID(), pos, m_granades[i].getStrength());
00993                         }
00994                         else {
00995                                 glPushMatrix();
00996                                 {
00997                                         pos = m_granades[i].getPos();
00998                                         glTranslatef(pos.x, pos.y, pos.z);
00999                                         m_objects[PLAY_OBJ_GRENADE]->draw();
01000                                 }
01001                                 glPopMatrix();
01002                         }
01003                 }
01004         }
01005 }
01006 
01007 /********************************************************************
01008  * Grenades Explode
01009  */
01010 void Play::grenadeExplode(int ownerID, Vec3 pos, float strength) {
01011         float dist;
01012 
01013         strength *= 7.5;
01014 
01015         // (mostly) FOR SERVER!
01016         for (unsigned int i=0; i<SPLAYER_MAX_PLAYERS; i++) {
01017                 if (g_players[i].state == PLAYER_STATE_OFFLINE)
01018                         continue;
01019                 
01020                 dist = (pos - g_players[i].pos).length();
01021                 if (dist <= 2.5f) {
01022                         if (dist <= 0.01f) dist = 0.01f;
01023                         this->dealDamage(ownerID, i, strength * (2.5f/dist));
01024                 }
01025         }
01026 
01027         // shake camera
01028         dist = (pos - g_players[g_myPlayerID].pos).length();
01029         if (dist < 0.5f) dist = 0.5f;
01030         m_parent->camera.shake(0.30f, 70.0f, 0.8f/(dist*dist));
01031 
01032         m_sounds[PLAY_SOUND_GRENADE].play((int)255/dist);
01033         createExplosion(pos + Vec3(0.0f, 0.25f, 0.0f), 1.0f);
01034 }
01035 
01036 /********************************************************************
01037  * Deal damage
01038  * This is FOR SERVER
01039  */
01040 void Play::dealDamage(int ownerID, int playerID, float damage) {
01041         if (g_players[playerID].state == PLAYER_STATE_USER && !g_players[playerID].extras[PLAY_EXTRAS_IMMORTAL])
01042                 g_players[playerID].life -= damage;
01043 
01044         // FOR SERVER
01045         if (gne->isServer() && g_players[playerID].life <= 0) {
01046                 g_players[playerID].life = 100.0f;
01047                 gne->setPlayerDeath(playerID, ownerID);
01048         }
01049 }
01050 
01051 /********************************************************************
01052  * Draw explosions
01053  */
01054 void Play::drawExplosions() {
01055         for (unsigned int i=0; i<MAX_EXPLOSIONS; i++) {
01056                 m_parent->renderer->setDepthFunc(LEQUAL);
01057                 m_parent->renderer->setMask(COLOR);
01058                 m_parent->renderer->setTextures(m_textures[PLAY_TEX_PARTICLE]);
01059                 m_parent->renderer->setBlending(ONE, ONE);
01060                 m_parent->renderer->apply();
01061                 if (m_explosions[i].isAlive()) {
01062                         m_explosions[i].drawAndUpdate(g_frameTime*0.001f);
01063                 }
01064         }
01065 }
01066 
01067 /********************************************************************
01068  * Draw projectiles
01069  */
01070 void Play::drawProjectiles() {
01071         m_parent->renderer->setTextures(m_textures[PLAY_TEX_GRENADE]);
01072         m_parent->renderer->apply();
01073         Vec3 pos;
01074         float dTime = g_frameTime*0.001f;
01075         int playerID;
01076 
01077         float dist;
01078 
01079         for (unsigned int i=0; i<MAX_PROJECTILES; i++) {
01080                 if (m_projectiles[i].isAlive()) {
01081                         m_projectiles[i].update(dTime);
01082 
01083                         pos = m_projectiles[i].getPos();
01084 
01085                         if (m_objLevel->collission(pos, 0.05f)) {
01086                                 createExplosion(pos, m_projectiles[i].getStrength());
01087                                 m_projectiles[i].die();
01088                                 dist = (g_players[g_myPlayerID].pos - pos).length();
01089                                 if (dist < 0.5f) dist = 0.5f;
01090                                 m_sounds[PLAY_SOUND_GUN_HIT].play((int)255/dist);
01091                         }
01092 
01093                         // FOR SERVER
01094                         else if ((playerID = this->playerCollission(pos, 0.25f)) != -1) {
01095                                 this->dealDamage(m_projectiles[i].getPlayerID(), playerID, m_projectiles[i].getStrength()*7.0f);
01096                                 m_projectiles[i].die();
01097                                 createExplosion(pos, m_projectiles[i].getStrength());
01098                         }
01099 
01100                         else {
01101                                 glPushMatrix();
01102                                         glTranslatef(pos.x, pos.y, pos.z);
01103                                         m_objects[PLAY_OBJ_GRENADE]->draw();
01104                                 glPopMatrix();
01105                         }
01106                 }
01107         }
01108 }
01109 
01110 /********************************************************************
01111  * Player collission
01112  */
01113 int Play::playerCollission(Vec3 pos, float size) {
01114         float dist;
01115 
01116         Vec2 pA(pos.x, pos.z);
01117         Vec2 pP;
01118 
01119         for (unsigned int i=0; i<SPLAYER_MAX_PLAYERS; i++) {
01120                 if (g_players[i].state == PLAYER_STATE_OFFLINE)
01121                         continue;
01122                 pP = Vec2(g_players[i].pos.x, g_players[i].pos.z);
01123                 dist = (pA - pP).length();
01124                 if (dist <= size)
01125                         return i;
01126         }
01127 
01128         return -1;
01129 }
01130 
01131 
01132 /********************************************************************
01133  * Set spawn player (FOR SERVER)
01134  */
01135 void Play::setSpawnPlayer(int playerID) {
01136 
01137 
01138         g_players[playerID].state = PLAYER_STATE_INVISIBLE;
01139         g_players[playerID].spawnTime = g_time + 100.0f;
01140 
01141         if (gne->isRunning() && gne->isServer()) {
01142                 gne->setPlayerState(playerID, g_players[playerID].state);
01143         }
01144 }
01145 
01146 /********************************************************************
01147  * Draw player
01148  */
01149 void Play::drawPlayers() {
01150         // draw ALL players
01151         for (unsigned int i=0; i<SPLAYER_MAX_PLAYERS; i++) {
01152                 if (g_players[i].state != PLAYER_STATE_OFFLINE)
01153                         drawPlayer(i);
01154         }
01155 }
01156 
01157 /********************************************************************
01158  * Draw player
01159  */
01160 void Play::drawPlayer(int playerID) {
01161         SPlayer *p = &g_players[playerID];
01162 
01163         if (p->state == PLAYER_STATE_OFFLINE || p->state == PLAYER_STATE_INVISIBLE)
01164                 return;
01165 
01166         if (!m_parent->camera.sphereInFrustum(p->pos, 0.25f))
01167                 return;
01168 
01169         glPushMatrix();
01170         {
01171                 glTranslatef(p->pos.x, p->pos.y, p->pos.z);
01172 
01173                 // immortal bubble
01174                 if (p->extras[PLAY_EXTRAS_IMMORTAL]) {
01175                         m_parent->renderer->setDepthFunc(LEQUAL);
01176                         m_parent->renderer->setMask(COLOR);
01177                         m_parent->renderer->setTextures(m_textures[PLAY_TEX_SPAWN_SPHERE]);
01178                         m_parent->renderer->setBlending(ONE, ONE);
01179                         m_parent->renderer->apply();
01180 
01181                         glPushMatrix();
01182                                 glTranslatef(0.0f, 0.40f, 0.0f);
01183                                 glRotatef(-g_time*0.15f, 0.25f, 0.85f, 0.45f);
01184                                 m_objects[PLAY_OBJ_SPHERE]->draw();
01185                         glPopMatrix();
01186                 }
01187 
01188                 // spawn bubble (and rotate)
01189                 if (p->state == PLAYER_STATE_SPAWNING) {
01190 
01191                         m_parent->renderer->setDepthFunc(LEQUAL);
01192                         m_parent->renderer->setMask(COLOR);
01193                         m_parent->renderer->setTextures(m_textures[PLAY_TEX_SPAWN_SPHERE]);
01194                         m_parent->renderer->setBlending(ONE, ONE);
01195                         m_parent->renderer->apply();
01196 
01197                         glPushMatrix();
01198                                 glTranslatef(0.0f, 0.40f, 0.0f);
01199                                 glRotatef(-g_time*0.15f, 0.25f, 0.85f, 0.45f);
01200                                 m_objects[PLAY_OBJ_SPHERE]->draw();
01201                         glPopMatrix();
01202 
01203                         glRotatef(g_time*0.6f, 0.0f, 1.0f, 0.0f); //drawSpawn(playerID);
01204                 }
01205                 else {
01206                         glRotatef(p->angle, 0.0f, 1.0f, 0.0f);
01207                 }
01208 
01209 
01210                 if (p->extras[PLAY_EXTRAS_INVISIBLE] != 0) {
01211                         glColor4f(0.2f, 0.2f, 0.2f, 0.15f);
01212                         m_parent->renderer->setBlending(ONE_MINUS_SRC_ALPHA, ONE);
01213                 }
01214                 m_parent->renderer->setTextures(p->textureID);
01215                 m_parent->renderer->apply();
01216 
01217                 //if (p->extras[PLAY_EXTRAS_INVISIBLE] == 0) {
01218                         glScalef(-0.1f, 0.1f, -0.1f);
01219                         g_models[playerID].render();
01220                 //}
01221 
01222                 //glPushAttrib(GL_LIGHTING_BIT);
01223                 //      glDisable(GL_LIGHTING);
01224                 //      m_model.renderBones();
01225                 //glPopAttrib();
01226 
01227         }
01228         glPopMatrix();
01229 
01230         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
01231         if (p->extras[PLAY_EXTRAS_INVISIBLE] == 0) {
01232                 drawShadow(p->pos, 0.35f);
01233         }
01234         m_parent->renderer->apply(); // for some reason needed for stencil test
01235 }
01236 
01237 /********************************************************************
01238  * Draw spawn
01239  */
01240 void Play::drawSpawn(int playerID) {
01241         //SPlayer *p = &g_players[playerID];
01242         //static float time = -1.0f;
01243 
01244         //if (p->state == PLAYER_STATE_SPAWNING && time == -1.0f) {
01245         //      time = g_time + 1500.0f;
01246         //}
01247 
01248         //if (g_time < time) {
01249         //      glRotatef(g_time*0.6f, 0.0f, 1.0f, 0.0f);
01250         //}
01251         //else {
01252         //      p->state = PLAYER_STATE_USER;
01253         //      m_particleSystems[p->ownsParticleSystem].die();
01254         //      p->ownsParticleSystem = -1;
01255         //      time = -1.0f;
01256         //}
01257 }
01258 
01259 /********************************************************************
01260  * Start particle system
01261  */
01262 int Play::startParticleSystem(Vec3 pos, int type) {
01263         for (unsigned int i=1; i<MAX_PARTICLESYSTEMS; i++) {
01264                 if (!m_particleSystems[i].isAlive()) {
01265                         m_particleSystems[i].loadPreset(type);
01266                         m_particleSystems[i].move(pos);
01267                         m_particleSystems[i].move(pos);
01268                         m_particleSystems[i].start();
01269                         return i;
01270                 }
01271         }
01272 
01273         return 1;
01274 }
01275 
01276 /********************************************************************
01277  * Set particle system position
01278  */
01279 void Play::setParticleSystemPos(int id, Vec3 pos) {
01280         if (m_particleSystems[id].isAlive())
01281                 m_particleSystems[id].move(pos);
01282 }
01283 
01284 /********************************************************************
01285  * Draw particle systems
01286  */
01287 void Play::drawParticleSystems() {
01288         m_parent->renderer->setDepthFunc(LEQUAL);
01289         m_parent->renderer->setMask(COLOR);
01290         m_parent->renderer->setTextures(m_textures[PLAY_TEX_PARTICLE]);
01291         m_parent->renderer->setBlending(ONE, ONE);
01292         m_parent->renderer->apply();
01293 
01294         for (unsigned int i=0; i<MAX_PARTICLESYSTEMS; i++) {    // Dead systems handled by "drawAndUpdate"
01295                 if (!m_parent->camera.sphereInFrustum(m_particleSystems[i].getPos(), 0.25f))
01296                         continue;
01297 
01298                 m_particleSystems[i].drawAndUpdate(&m_parent->camera, g_frameTime*0.001f);
01299         }
01300 }
01301 
01302 /********************************************************************
01303  * Draw shadow
01304  */
01305 void Play::drawShadow(Vec3 pos, float size) {
01306 
01307         m_parent->renderer->setMask(COLOR);
01308         m_parent->renderer->setTextures(m_textures[PLAY_TEX_SHADOW]);
01309         m_parent->renderer->setBlending(DST_COLOR, ZERO);
01310         m_parent->renderer->apply();
01311 
01312         glPushAttrib(GL_LIGHTING_BIT);
01313         {
01314                 glDisable(GL_LIGHTING);
01315 
01316                 glBegin(GL_QUADS);
01317                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01318                         glVertex3f(pos.x-size, 0.001f, pos.z-size);
01319 
01320                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01321                         glVertex3f(pos.x-size, 0.001f, pos.z+size);
01322 
01323                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01324                         glVertex3f(pos.x+size, 0.001f, pos.z+size);
01325 
01326                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01327                         glVertex3f(pos.x+size, 0.001f, pos.z-size);
01328                 glEnd();
01329 
01330                 //glEnable(GL_LIGHTING);        // can be removed.. I think
01331 
01332         }
01333         glPopAttrib();
01334 }
01335 
01336 /********************************************************************
01337  * Set player cam
01338  */
01339 void Play::setPlayerCam(int playerID) {
01340         float pitch = 55.0f;
01341         float heading = 90.0f;
01342         Vec3 pos = g_players[playerID].pos+Vec3(-7.0f, 10.75f, 0.0f);
01343 
01344 
01345         if (g_players[playerID].extras[PLAY_EXTRAS_FLIPVIEW] > 0) {
01346                 pitch = 125.0f;
01347                 pos = g_players[playerID].pos+Vec3(7.0f, 10.75f, 0.0f);
01348         }
01349 
01350         if (g_players[playerID].extras[PLAY_EXTRAS_SHAKE] > 0) {
01351                 pitch += cosf(g_time*0.01f)*2.2f;
01352                 heading += sinf(g_time*0.01f)*2.5f;
01353 
01354         }
01355 
01356         m_parent->camera.setPitch(pitch);
01357         m_parent->camera.setHeading(heading);
01358         m_parent->camera.setPosition(pos);
01359 }
01360 
01361 /********************************************************************
01362  * Draw avatar
01363  */
01364 void Play::drawAvatar(int model, bool clear) {
01365         static float x = 0.0f;
01366         float size = 25.0f;
01367         float y = 45.0f;
01368 
01369         if (clear)
01370                 x = 55.0f;
01371         else
01372                 x += 75.0f;
01373 
01374 
01375         m_parent->renderer->setMask(COLOR);
01376         m_parent->renderer->setTextures(m_textures[model]);
01377         m_parent->renderer->setBlending(ONE, ONE);
01378         m_parent->renderer->apply();
01379 
01380         //glPushAttrib(GL_LIGHTING_BIT);
01381         //{
01382         //      glDisable(GL_LIGHTING);
01383 
01384                 glBegin(GL_QUADS);
01385                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01386                         glVertex2f(x-size, y-size);
01387 
01388                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01389                         glVertex2f(x-size, y+size);
01390 
01391                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01392                         glVertex2f(x+size, y+size);
01393 
01394                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01395                         glVertex2f(x+size, y-size);
01396                 glEnd();
01397 
01398                 //glEnable(GL_LIGHTING);        // can be removed.. I think
01399 
01400         //}
01401         //glPopAttrib();
01402 
01403 }
01404 
01405 void Play::drawLifebar() {
01406         float height = 10.0f;
01407         float mWidth = 150.0f;
01408         float width = g_players[g_myPlayerID].life * 1.5f;
01409         float x = g_width - 25.0f;
01410         float y = g_height - height - 15.0f;
01411         float border = 2.0f;
01412         bool glow = false;
01413         
01414         if (width < 0.0f)
01415                 width = 0.0f;
01416 
01417         if (width > mWidth) {
01418                 glow = true;
01419                 width = mWidth;
01420         }
01421 
01422         m_parent->renderer->setMask(COLOR);
01423         m_parent->renderer->setTextures(m_textures[PLAY_TEX_LIFEBAR_BG]);
01424         m_parent->renderer->setBlending(ONE, ONE);
01425         m_parent->renderer->apply();
01426 
01427         glBegin(GL_QUADS);
01428                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01429                 glVertex2f(x-width+border, y-height+border);
01430 
01431                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01432                 glVertex2f(x-width+border, y+height-border);
01433 
01434                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01435                 glVertex2f(x-border, y+height-border);
01436 
01437                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01438                 glVertex2f(x-border, y-height+border);
01439         glEnd();
01440 
01441 
01442         m_parent->renderer->setMask(COLOR);
01443         m_parent->renderer->setTextures(m_textures[PLAY_TEX_LIFEBAR_FRAME]);
01444         m_parent->renderer->setBlending(DST_COLOR, ZERO);
01445         m_parent->renderer->apply();
01446 
01447         glBegin(GL_QUADS);
01448                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01449                 glVertex2f(x-mWidth, y-height);
01450 
01451                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01452                 glVertex2f(x-mWidth, y+height);
01453 
01454                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01455                 glVertex2f(x, y+height);
01456 
01457                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01458                 glVertex2f(x, y-height);
01459         glEnd();
01460 
01461         if (glow || g_players[g_myPlayerID].extras[PLAY_EXTRAS_IMMORTAL]) {
01462                 float c = 0.7f + sinf(g_time*0.01f)*0.3f;
01463                 glColor4f(c,c,c,c);
01464                 m_parent->renderer->setMask(COLOR);
01465                 m_parent->renderer->setTextures(m_textures[PLAY_TEX_LIFEBAR_GLOW]);
01466                 m_parent->renderer->setBlending(ONE, ONE);
01467                 m_parent->renderer->apply();
01468 
01469                 glBegin(GL_QUADS);
01470                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01471                         glVertex2f(x-mWidth-border, y-height-border);
01472 
01473                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01474                         glVertex2f(x-mWidth-border, y+height+border);
01475 
01476                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01477                         glVertex2f(x+border, y+height+border);
01478 
01479                         glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01480                         glVertex2f(x+border, y-height-border);
01481                 glEnd();
01482         }
01483 
01484         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
01485 }
01486 
01487 /********************************************************************
01488  * Apply extras
01489  */
01490 void Play::applyExtras(int playerID, int type, bool add) {
01491         //------------------------------------------------------------
01492         // Add extras
01493         //------------------------------------------------------------
01494         if (add) {
01495                 switch (type) {
01496                         case PLAY_EXTRAS_LIFE:                                          // life
01497                                 g_players[playerID].life = 150.0f;
01498                                 break;
01499 
01500                         case PLAY_EXTRAS_AMMO:                                          // ammo
01501                                 g_players[playerID].ammo += 25;
01502                                 break;
01503 
01504                         case PLAY_EXTRAS_SLOW:                                          // slow down
01505                                 g_players[playerID].extras[type] = 1;
01506                                 g_players[playerID].timeExtras[type] = g_time + 15000.0f;
01507                                 break;
01508 
01509                         case PLAY_EXTRAS_SHAKE:                                         // shake
01510                                 g_players[playerID].extras[type] = 1;
01511                                 g_players[playerID].timeExtras[type] = g_time + 12500.0f;
01512                                 break;
01513 
01514                         case PLAY_EXTRAS_FLIPVIEW:                                      // flip view
01515                                 g_players[playerID].extras[type] = 1;
01516                                 g_players[playerID].timeExtras[type] = g_time + 12500.0f;
01517                                 break;
01518 
01519                         case PLAY_EXTRAS_FAST:                                          // fast
01520                                 g_players[playerID].extras[type] = 1;
01521                                 g_players[playerID].timeExtras[type] = g_time + 15000.0f;
01522                                 break;
01523 
01524                         case PLAY_EXTRAS_INVISIBLE:                                     // invisible
01525                                 g_players[playerID].extras[type] = 1;
01526                                 g_players[playerID].timeExtras[type] = g_time + 15000.0f;
01527                                 break;
01528 
01529                         case PLAY_EXTRAS_IMMORTAL:                                      // immortal
01530                                 g_players[playerID].extras[type] = 1;
01531                                 g_players[playerID].timeExtras[type] = g_time + 15000.0f;
01532                                 break;
01533 
01534                         default:                                                                        // not defined
01535                                 break;
01536                 }
01537         }
01538         //------------------------------------------------------------
01539         // Remove extras
01540         //------------------------------------------------------------
01541         else {
01542                 switch (type) {
01543                         case PLAY_EXTRAS_LIFE:                                          // life
01544                                 break;
01545 
01546                         case PLAY_EXTRAS_AMMO:                                          // ammo
01547                                 break;
01548 
01549                         default:
01550                                 g_players[playerID].extras[type] = 0;
01551                                 g_players[playerID].timeExtras[type] = 0.0f;
01552                                 break;
01553                 }
01554         }
01555 }
01556 
01557 /********************************************************************
01558  * New extras
01559  */
01560 void Play::newExtras(int type, float x, float z) {
01561         float maxTime = 0.0f;
01562         int avaiable = 0;
01563 
01564         for (unsigned int i=0; i<PLAY_EXTRAS_SIMULTANEOUS; i++) {
01565                 if (m_extras[i].type == PLAY_EXTRAS_NONE) {
01566                         avaiable = i;
01567                         break;
01568                 }
01569                 
01570                 if (m_extras[i].time > maxTime) {
01571                         maxTime = m_extras[i].time;
01572                         avaiable = i;
01573                 }
01574         }
01575 
01576 
01577         m_extras[avaiable].type = type;
01578         m_extras[avaiable].time = g_time;
01579         m_extras[avaiable].pos = Vec3(x, 0.0f, z);
01580 }
01581 
01582 /********************************************************************
01583  * Deal extras (FOR SERVER only)
01584  */
01585 void Play::dealExtras() {
01586         static float time = 0.0f;
01587         static float max = pow(PLAY_EXTRAS, 2);
01588 
01589         if (!gne->isServer())
01590                 return;
01591 
01592         // deal one extras
01593         if (time <= g_time) {
01594                 Vec3 pos = m_objLevel->getExtras();
01610                 float r = ((float)rand() / (float)RAND_MAX)*(max);
01611 
01612                 //int type = (int)sqrt(r);
01613                 //if (type < 0) type = 0;
01614                 //else if (type > PLAY_EXTRAS-1) type = PLAY_EXTRAS - 1;
01615 
01616                 int type = (int)round(((float)rand() / (float)RAND_MAX)*(PLAY_EXTRAS-1));
01617 
01618                 //LOG_MISC(("New extras dealed (%d, %f, %f)", type, pos.x, pos.z));
01619 
01620                 gne->dealExtras(type, pos.x, pos.z, 1);
01621 
01622                 time = g_time + 10000.0f;
01623         }
01624 }
01625 
01626 /********************************************************************
01627  * Draw extras
01628  */
01629 void Play::drawExtras() {
01630         float size = 0.20f;
01631 
01632         for (unsigned int i=0; i<PLAY_EXTRAS_SIMULTANEOUS; i++) {
01633                 if (m_extras[i].type == PLAY_EXTRAS_NONE)
01634                         continue;
01635 
01636                 m_parent->renderer->setMask(COLOR);
01637                 m_parent->renderer->setTextures(m_textures[PLAY_TEX_EXTRAS_OTHER]);
01638                 m_parent->renderer->setBlending(ONE, ONE);
01639                 m_parent->renderer->apply();
01640 
01641                 glPushMatrix();
01642                 {
01643                         glTranslatef(m_extras[i].pos.x, m_extras[i].pos.y, m_extras[i].pos.z);
01644                         glRotatef((m_extras[i].time + g_time)*0.1f, 0.0f, 1.0f, 0.0f);
01645 
01646                         glBegin(GL_QUADS);
01647                                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
01648                                 glVertex3f(-size, size+0.0f, 0.0f);
01649 
01650                                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
01651                                 glVertex3f(-size, size+size*2.0f, 0.0f);
01652 
01653                                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
01654                                 glVertex3f(size, size+size*2.0f, 0.0f);
01655 
01656                                 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
01657                                 glVertex3f(size, size+0.0f, 0.0f);
01658                         glEnd();
01659                 }
01660                 glPopMatrix();
01661         }
01662 }
01663 
01664 /********************************************************************
01665  * Bot
01666  */
01667 void Play::bot(int playerID) {
01668         static Vec3 goal[SPLAYER_MAX_PLAYERS];
01669         static float lastGrenade[SPLAYER_MAX_PLAYERS] = {0};
01670         static float lastProjectile[SPLAYER_MAX_PLAYERS] = {0};
01671         static int gunPos[SPLAYER_MAX_PLAYERS] = {0};
01672 
01673         SPlayer *player = &g_players[playerID];
01674 
01675         if (player->state != PLAYER_STATE_USER) {
01676                 goal[playerID] = Vec3(0.0f, 0.0f, 0.0f);
01677                 return;
01678         }
01679 
01680         if (goal[playerID].length() == 0.0f) {
01681                 float dx = (1.0f*(float)rand() / (float)RAND_MAX - 0.5f);
01682                 float dz = (1.0f*(float)rand() / (float)RAND_MAX - 0.5f);
01683 
01684                 Vec3 wanted = player->pos - (player->pos - g_players[g_myPlayerID].pos).normalize()*0.5f + Vec3(dx, 0.0f, dz);
01685 
01686                 if (!m_objLevel->collission(wanted, 0.30f)) {
01687                         goal[playerID] = wanted;
01688                 }
01689                 else {
01690                         int n = 0;
01691                         while (n++ < 10) {
01692                                 dx = (2.0f*(float)rand() / (float)RAND_MAX - 1.0f);
01693                                 dz = (2.0f*(float)rand() / (float)RAND_MAX - 1.0f);
01694                                 Vec3 pos(wanted.x + dx, wanted.y, wanted.z + dz);
01695                                 if (m_objLevel->collission(pos, 0.30f) || m_objLevel->isWater(pos)) {
01696                                 }
01697                                 else {
01698                                         goal[playerID] = pos;
01699                                         break;
01700                                 }
01701                         }
01702                 }
01703         }
01704 
01705         Vec3 dir = player->pos - goal[playerID];
01706         dir = dir.normalize()*g_frameTime*0.002f;
01707 
01708         player->pos -= dir;
01709         player->dir = dir;
01710         player->angle = atanf(dir.x/dir.z)*180.0f/PI + (dir.z >= 0.0f ? 0.0f : -180.0f);
01711 
01712         //----------- WEAPONS ------------------
01713         if ((player->pos - g_players[g_myPlayerID].pos).length() <= 4.00f) {
01714 
01715                 float angle = -player->angle*PIdiv180;
01716                 float cosA = cos(angle);
01717                 float sinA = sin(angle);
01718 
01719                 // throw grenade!
01720                 if (g_time - lastGrenade[playerID] > 500.0f) {
01721                         Vec3 gunVec = Vec3(0.0f, 0.25f, 0.0f);
01722                         if (g_models[playerID].numGuns > 0) {
01723                                 if (++gunPos[playerID] >= g_models[playerID].numGuns) gunPos[playerID] = 0;
01724                                 
01725                                 gunVec = g_models[playerID].guns[gunPos[playerID]];
01726 
01727                                 Vec3 tmp = gunVec;
01728                                 gunVec.x = tmp.x*cosA-tmp.z*sinA;
01729                                 gunVec.z = tmp.x*sinA+tmp.z*cosA;
01730                         }
01731 
01732                         lastGrenade[playerID] = g_time + (1000.0f*(float)rand() / (float)RAND_MAX);;
01733                         throwGrenade(playerID, player->pos + gunVec, -player->dir*350.0f + Vec3(0.0f, 6.0f, 0.0f), 3.0f, 1.0f);
01734                 }
01735 
01736                 // fire projectile
01737                 if (g_time - lastProjectile[playerID] > player->weapon.reload) {
01738                         Vec3 gunVec = Vec3(0.0f, 0.25f, 0.0f);
01739                         if (g_models[playerID].numGuns > 0) {
01740                                 if (++gunPos[playerID] >= g_models[playerID].numGuns) gunPos[playerID] = 0;
01741                                 
01742                                 gunVec = g_models[playerID].guns[gunPos[playerID]];
01743 
01744                                 Vec3 tmp = gunVec;
01745                                 gunVec.x = tmp.x*cosA-tmp.z*sinA;
01746                                 gunVec.z = tmp.x*sinA+tmp.z*cosA;
01747                         }
01748 
01749                         
01750                         lastProjectile[playerID] = g_time + (1000.0f*(float)rand() / (float)RAND_MAX);
01751                         fireProjectile(playerID, player->pos + gunVec, -player->dir*500.0f*player->weapon.speed, player->weapon.power);
01752                 }
01753         }
01754 
01755         //--------------------------------------
01756 
01757         player->moving = true;
01758 
01759         if ((player->pos - goal[playerID]).length() <= 0.01f)
01760                 goal[playerID] = Vec3(0.0f, 0.0f, 0.0f);
01761 
01762         //setPlayerCam(1);
01763 }

Generated on Sun Jun 5 15:47:05 2005 for Defacto by  doxygen 1.4.3