00001
00007 #include "Play.h"
00008
00009
00010
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
00024
00025 Play::~Play() {
00026 unload();
00027 }
00028
00029
00030
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
00042
00043
00044
00045
00067
00068
00069
00070
00071
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
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 for (unsigned int i=0; i<PLAY_EXTRAS_SIMULTANEOUS; i++) {
00100 m_extras[i].type = PLAY_EXTRAS_NONE;
00101 }
00102
00103
00104
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
00117 for (i=0; i<GL_MAX_LIGHTS; i++) {
00118 glDisable(GL_LIGHT0+i);
00119 }
00120
00121
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
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
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
00191
00192 bool Play::loadObjects() {
00193
00194
00195
00196
00197
00198
00199 char file[256] = {0};
00200
00201 sprintf(file, "data\\lvls\\%s",g_galaxies[g_gameInfo.currLvl[0]].lvls[g_gameInfo.currLvl[1]].file);
00202
00203
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
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
00224
00225 }
00226
00227 return true;
00228 }
00229
00230
00231
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
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
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
00298
00299
00300
00301
00302 for (i=0; i<SPLAYER_MAX_PLAYERS; i++) {
00303 g_models[i].clear();
00304 }
00305
00306
00307
00308
00309
00310 LOG_SUCCESS(("Play game unloaded"));
00311 m_loaded = false;
00312 return true;
00313 }
00314
00315
00316
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
00334
00335
00336
00337
00338 this->networkLoop();
00339 this->serverLoop();
00340
00341
00342
00343
00344
00345
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
00370
00371 switch (player->rotation) {
00372 case PLAYER_ROTATION_NONE:
00373 break;
00374
00375 case PLAYER_ROTATION_LEFT:
00376 player->angle += rotSpeed;
00377 rotationChanged = true;
00378 break;
00379
00380 case PLAYER_ROTATION_RIGHT:
00381 player->angle -= rotSpeed;
00382 rotationChanged = true;
00383 break;
00384
00385 default:
00386 break;
00387 }
00388
00389
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
00399
00400 switch (player->moving) {
00401 case PLAYER_MOVING_NONE:
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:
00415 player->speed = maxSpeed;
00416 player->moveVal = -1;
00417 moveChanged = true;
00418 break;
00419
00420 case PLAYER_MOVING_BACKWARD:
00421 player->speed = maxSpeed;
00422 player->moveVal = 1;
00423 moveChanged = true;
00424 break;
00425 }
00426
00427 if (moveChanged) {
00428 pos = player->pos;
00429 speed = player->speed*player->moveVal*g_frameTime;
00430
00431
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
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)) {
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
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);
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) {
00474
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
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)
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
00576
00577
00578
00579
00580
00581
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
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) {
00631
00632
00633
00634
00635
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']) {
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
00665 }
00666 }
00667
00668 if (m_parent->keys['X']) {
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
00691 }
00692 }
00693
00694 }
00695
00696
00697
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
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
00746
00747 m_objLevel->drawObjects();
00748
00749
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
00788
00789 m_objLevel->drawObjects();
00790
00791
00792 drawPlayers();
00793
00794 glDisable(GL_STENCIL_TEST);
00795
00796 }
00797
00798
00799
00800 else {
00801
00802 glEnable(GL_LIGHTING);
00803
00804 m_objLevel->drawFloor();
00805 m_objLevel->drawWalls();
00806 m_objLevel->drawWater();
00807
00808
00809
00810 m_objLevel->drawObjects();
00811
00812
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
00831
00832 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00833 m_parent->defaultFont->startTextMode();
00834
00835
00836
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
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 this->drawLifebar();
00859
00860 }
00861
00862
00863
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
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();
00937
00938 return true;
00939 }
00940
00941
00942
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
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
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
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
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
01009
01010 void Play::grenadeExplode(int ownerID, Vec3 pos, float strength) {
01011 float dist;
01012
01013 strength *= 7.5;
01014
01015
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
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
01038
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
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
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
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
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
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
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
01148
01149 void Play::drawPlayers() {
01150
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
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
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
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);
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
01218 glScalef(-0.1f, 0.1f, -0.1f);
01219 g_models[playerID].render();
01220
01221
01222
01223
01224
01225
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();
01235 }
01236
01237
01238
01239
01240 void Play::drawSpawn(int playerID) {
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 }
01258
01259
01260
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
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
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++) {
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
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
01331
01332 }
01333 glPopAttrib();
01334 }
01335
01336
01337
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
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
01381
01382
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
01399
01400
01401
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
01489
01490 void Play::applyExtras(int playerID, int type, bool add) {
01491
01492
01493
01494 if (add) {
01495 switch (type) {
01496 case PLAY_EXTRAS_LIFE:
01497 g_players[playerID].life = 150.0f;
01498 break;
01499
01500 case PLAY_EXTRAS_AMMO:
01501 g_players[playerID].ammo += 25;
01502 break;
01503
01504 case PLAY_EXTRAS_SLOW:
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:
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:
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:
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:
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:
01530 g_players[playerID].extras[type] = 1;
01531 g_players[playerID].timeExtras[type] = g_time + 15000.0f;
01532 break;
01533
01534 default:
01535 break;
01536 }
01537 }
01538
01539
01540
01541 else {
01542 switch (type) {
01543 case PLAY_EXTRAS_LIFE:
01544 break;
01545
01546 case PLAY_EXTRAS_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
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
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
01593 if (time <= g_time) {
01594 Vec3 pos = m_objLevel->getExtras();
01610 float r = ((float)rand() / (float)RAND_MAX)*(max);
01611
01612
01613
01614
01615
01616 int type = (int)round(((float)rand() / (float)RAND_MAX)*(PLAY_EXTRAS-1));
01617
01618
01619
01620 gne->dealExtras(type, pos.x, pos.z, 1);
01621
01622 time = g_time + 10000.0f;
01623 }
01624 }
01625
01626
01627
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
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
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
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
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
01763 }