E:/Eigene Dateien/Eigene Projekte/c0re/Level.cpp

Go to the documentation of this file.
00001 /*
00002         This file is part of c0re.
00003 
00004         c0re is a multiplayer RTS on a hexagonal map with an evolving unit concept.
00005     Copyright (C) 2007 Stephan Hofmann
00006 
00007     c0re is free software: you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation, either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "Level.h"
00022 
00023 #include "system.h"
00024 #include <GL/gl.h>
00025 #include <GL/glu.h>
00026 #include <time.h>
00027 #include <stdio.h>
00028 #include <fstream>
00029 #include "math.h"
00030 
00031 #include "myTools.h"
00032 #include "Window.h"
00033 #include "Player.h"
00034 #include "Interface.h"
00035 #include "DAEffect.h"
00036 #include "EventInterface.h"
00037 
00038 const unsigned int Level::roundTime = 20;
00039 const int Level::interfaceSizeWidth = 500;
00040 const int Level::interfaceSizeHeight = 150;
00041 
00042 Level::Level(Window *p_window) : GLInterface(p_window), eventList(10000)
00043 {
00044 
00045         bindings["+ESC"] = "QUIT";
00046         bindings["+PGUP"] = "ZOOMIN";
00047         bindings["+PGDOWN"] = "ZOOMOUT";
00048         bindings["+LEFTARROW"] = "SCROLLLEFT";
00049         bindings["+UPARROW"] = "SCROLLUP";
00050         bindings["+RIGHTARROW"] = "SCROLLRIGHT";
00051         bindings["+DOWNARROW"] = "SCROLLDOWN";
00052         bindings["+SPACE"] = "";
00053         bindings["+LMOUSE"] = "!SELECT"; //only called once
00054         bindings["+RMOUSE"] = "!GRABSCREEN";
00055         bindings["-RMOUSE"] = "!RELEASESCREEN";
00056         bindings["+WMouse"] = "!ZOOMIN";
00057         bindings["-WMouse"] = "!ZOOMOUT";
00058         
00059         functions["QUIT"] = &FunctionHandler::quit;
00060         functions["ZOOMIN"] = &FunctionHandler::zoomIn;
00061         functions["ZOOMOUT"] = &FunctionHandler::zoomOut;
00062         functions["SCROLLLEFT"] = &FunctionHandler::scrollLeft;
00063         functions["SCROLLUP"] = &FunctionHandler::scrollUp;
00064         functions["SCROLLRIGHT"] = &FunctionHandler::scrollRight;
00065         functions["SCROLLDOWN"] = &FunctionHandler::scrollDown;
00066         functions["SELECT"] = &FunctionHandler::select;
00067         functions["GRABSCREEN"] = &FunctionHandler::grabScreen;
00068         functions["RELEASESCREEN"] = &FunctionHandler::releaseScreen;
00069         functions["SCROLLSCREEN"] = &FunctionHandler::scroll;
00070         functions["STANDARDACTION"] = &FunctionHandler::standardAction;
00071         functions["SETTLE"] = &FunctionHandler::settle;
00072         functions["SETSPAWNDESTINATION"] = &FunctionHandler::setSpawnDestination;
00073         functions["SELECTBONUS"] = &FunctionHandler::selectBonus;
00074         
00075         playerInterface = 0;
00076         network = 0;
00077 }
00078 
00079 Level::~Level()
00080 {
00081         if (playerInterface != 0)
00082                 delete playerInterface;
00083 }
00084 
00085 int Level::run()
00086 {
00087 
00088         int ret = 0;
00089 
00090         // if we multiply this with clock() than we have a better GetTickCount
00091         double clock_per_ms = 1000.0 / (double)CLOCKS_PER_SEC;
00092         // the time a GE Tick is over
00093         double endTime = clock() * clock_per_ms;
00094         // the time we jumped in
00095         double globStartTime = clock() * clock_per_ms;
00096 
00097         //Variable for the current time;
00098         double curTime;
00099 
00100         //init rounds
00101         round = 0;
00102 
00103         bool run = true;
00104 
00105         do
00106         {
00107                 //increase roundcounter
00108                 round++;
00109 
00110                 // endTime will incresed with our round delta
00111                 endTime += roundTime;
00112                 
00113                 //check for input-messages
00114                 run = checkInput();
00115 
00116                 //compute everything on the grid
00117                 //compute();
00118 
00119                 //process events
00120                 std::list< EventInterface* >::iterator it;
00121                 for (it = eventList[0].begin(); it != eventList[0].end(); it++)
00122                 {
00123                         (*it)->compute(this);
00124                         delete (*it);
00125                 }
00126                 eventList[0].clear();
00127                 eventList.moveOn();
00128 
00129 
00130                 //compute visibility
00131                 computeVisibility();
00132 
00133                 //render szene
00134                 setViewportCamera();
00135                 initViewCamera();
00136                 renderScene();
00137                 //render interface
00138                 setViewportInterface();
00139                 initViewInterface();
00140                 renderInterface();
00141                 //finished rendering
00142                 glFlush();
00143                 window->swapBuffers();
00144 
00145                 // sleep, until we reached endtime
00146                 do
00147                 {
00148                         // sleep
00149                         sleep(0);
00150                         // compute curTime
00151                         curTime = clock() * clock_per_ms;
00152                 } 
00153                 while (curTime < endTime);
00154 
00155         }
00156         while (run);
00157 
00158         return ret;
00159 }
00160 
00161 int Level::compute()
00162 {
00163         int ret = 0;
00164         unsigned int i,j;
00165         for (i = 0; i < grid.size(); i++)
00166         {       
00167                 for (j = 0; j < grid[i].size(); j++)
00168                 {
00169                         if (grid[i][j] != 0)
00170                         {
00171                                 if (grid[i][j]->unit != 0) //compute only units
00172                                 {
00173                                         grid[i][j]->unit->compute(grid[i][j], this);
00174                                 }
00175                         }
00176                 }
00177         }
00178         return ret;
00179 }
00180 
00181 int Level::initViewCamera(bool resetMatrix)
00182 {
00183         int ret = 0;
00184         
00185         //we are working on the porjection matrix oly.
00186         glMatrixMode(GL_PROJECTION);
00187 
00188         if (resetMatrix)
00189         {
00190                 //reset camera
00191                 glLoadIdentity();
00192         }
00193 
00194         //perspective view (45deg fov)
00195         gluPerspective(45.0, (GLfloat)window->width/(GLfloat)window->height, 0.125, 1048575.875);
00196         
00197         //rotate so we look to -Z
00198         glRotated(180.0, 0.0, 1.0, 0.0);
00199         //translate to camera position
00200         glTranslated(position.x, position.y, position.z);
00201 
00202         return ret;
00203 }
00204 
00205 int Level::initViewInterface(bool resetMatrix)
00206 {
00207         int ret = 0;
00208 
00209         //we are working on the porjection matrix oly.
00210         glMatrixMode(GL_PROJECTION);
00211 
00212         if (resetMatrix)
00213         {
00214                 //reset camera
00215                 glLoadIdentity();
00216         }
00217 
00218         //perspectivew view with 45deg fov
00219         gluPerspective(45.0, interfaceSizeWidth/interfaceSizeHeight, 0.125, 1048575.875);
00220 
00221         //rotate so we look to -Z
00222         glRotated(180.0, 0.0, 1.0, 0.0);
00223 
00224         //trasnlate fixed so we have the same position for the interface
00225         glTranslated(0.0, 0.0, 0.4);
00226 
00227         return ret;
00228 }
00229 
00230 int Level::renderScene(bool p_normal)
00231 {
00232         int ret = 0;
00233 
00234         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00235         glMatrixMode(GL_MODELVIEW);
00236         glLoadIdentity();
00237 
00238         glDisable(GL_DEPTH_TEST);
00239         //render fields
00240         Vector3d pos;
00241         unsigned int i,j;
00242         for (i = 0; i < grid.size(); i++)
00243         {       
00244                 for (j = 0; j < grid[i].size(); j++)
00245                 {
00246                         if (grid[i][j] != 0)
00247                         {
00248                                 grid[i][j]->render(pos);
00249                                 if (p_normal)
00250                                         grid[i][j]->renderChild(pos, this);
00251                         }
00252                         pos.y += 0.87;
00253                 }
00254                 pos.x += 0.75;
00255                 if ((i%2) == 0)
00256                 {
00257                         pos.y = 0.44;
00258                 }
00259                 else
00260                 {
00261                         pos.y = 0.0;
00262                 }
00263         }
00264         //now all effects
00265         std::list<Texture*>::iterator it;
00266 
00267         if (p_normal)
00268                 for (it = effects.begin(); it != effects.end(); it++)
00269                 {
00270                         (*it)->render();
00271                 }
00272 
00273         glEnable(GL_DEPTH_TEST);
00274         
00275         return ret;
00276 }
00277 
00278 int Level::renderInterface()
00279 {
00280         int ret = 0;
00281 
00282         playerInterface->render();
00283 
00284         return ret;
00285 }
00286 
00287 bool Level::checkInput()
00288 {
00289         bool ret = true;
00290         singleCommands.clear();
00291 
00292         //check messages
00293         if (window->checkMessages() == 1)
00294                 ret = false;
00295 
00296         std::string msg;
00297         std::map<std::string, std::string>::iterator bind_it;
00298         while (inputMessages.size() > 0)
00299         {
00300                 msg = inputMessages.front();
00301                 inputMessages.pop_front();
00302 
00303                 ret &= (msg != "QUIT");
00304                 if (msg == "-RMOUSE")
00305                         std::string t = msg;
00306                 if (msg == "BUTTONSETTLE")
00307                         int t = 3;
00308                 bind_it = bindings.find(msg);
00309                 if (bind_it != bindings.end())
00310                 {
00311                         //single command?
00312                         if (bind_it->second.find("!") == 0)
00313                         {
00314                                 singleCommands.push_back(bind_it->second.substr(1));
00315                         }
00316                         else
00317                         {
00318                                 currentCommands.remove(bind_it->second);
00319                                 currentCommands.push_back(bind_it->second);
00320                         }
00321                 }
00322                 else
00323                 {
00324                         //check if an old command has to be removed
00325                         
00326                         bind_it = bindings.find(msg.replace(0, 1, "+"));
00327                         if (bind_it != bindings.end())
00328                         {
00329                                 currentCommands.remove(bind_it->second);
00330                         }
00331                 }
00332         }
00333         //afterwards run commands
00334         std::list<std::string>::iterator it;
00335         for (it = currentCommands.begin(); it != currentCommands.end(); it++)
00336         {
00337                 std::vector<std::string> param; 
00338                 if (functions.find(*it) != functions.end())
00339                         (*functions[*it])(param, this);
00340         }
00341         for (it = singleCommands.begin(); it != singleCommands.end(); it++)
00342         {
00343                 std::vector<std::string> param; 
00344                 if (functions.find(*it) != functions.end())
00345                         (*functions[*it])(param, this);
00346         }
00347         return ret;
00348 }
00349 
00350 bool Level::setVisible(unsigned int p_x, unsigned int p_y)
00351 {
00352         bool ret = false;
00353         if ((0 <= p_x) && (p_x < grid.size()) && (0 <= p_y) && (p_y < grid[p_x].size()))
00354                 if (grid[p_x][p_y] != 0)
00355                         ret = grid[p_x][p_y]->isVisible = true;
00356         return ret;
00357 }
00358 
00359 int Level::computeVisibility()
00360 {
00361         int ret = 0;
00362 
00363         unsigned int i,j;
00364         for (i = 0; i < grid.size(); i++)
00365                 for (j = 0; j < grid[i].size(); j++)
00366                         if (grid[i][j] != 0)
00367                                 grid[i][j]->isVisible = grid[i][j]->isSettleRange; //make ivisible
00368 
00369         for (i = 0; i < grid.size(); i++)
00370                 for (j = 0; j < grid[i].size(); j++)
00371                         if (grid[i][j] != 0)
00372                                 if (grid[i][j]->unit != 0)
00373                                 {
00374                                         setVisible(i - 2, j - 1);
00375                                         setVisible(i - 2, j + 0);
00376                                         setVisible(i - 2, j + 1);
00377                                         
00378                                         if (i % 2 == 0)
00379                                                 setVisible(i - 1, j - 2);
00380                                         setVisible(i - 1, j - 1);
00381                                         setVisible(i - 1, j + 0);
00382                                         setVisible(i - 1, j + 1);
00383                                         if (i % 2 == 1)
00384                                                 setVisible(i - 1, j + 2);
00385 
00386                                         setVisible(i + 0, j - 2);
00387                                         setVisible(i + 0, j - 1);
00388                                         setVisible(i + 0, j + 0);
00389                                         setVisible(i + 0, j + 1);
00390                                         setVisible(i + 0, j + 2);
00391 
00392                                         if (i % 2 == 0)
00393                                                 setVisible(i + 1, j - 2);
00394                                         setVisible(i + 1, j - 1);
00395                                         setVisible(i + 1, j + 0);
00396                                         setVisible(i + 1, j + 1);
00397                                         if (i % 2 == 1)
00398                                                 setVisible(i + 1, j + 2);
00399 
00400 
00401                                         setVisible(i + 2, j - 1);
00402                                         setVisible(i + 2, j + 0);
00403                                         setVisible(i + 2, j + 1);
00404 
00405                                 }
00406         return ret;
00407 }
00408 
00409 int Level::load(std::string p_filename)
00410 {
00411         int ret = 0;
00412 
00413         this->initGL();
00414 
00415         playerInterface = new Interface(this);
00416         playerInterface->load("green", "blue");
00417 
00418         //initialize
00419         int sizeX = 50;
00420         int sizeY = 50;
00421         
00422         std::vector<Field*> line(sizeY);
00423         std::vector< std::vector<Field*> > _grid(sizeX, line);
00424 
00425         grid.assign(_grid.begin(), _grid.end());
00426 
00427         for (unsigned int i = 0; i < grid.size(); i++)
00428         {
00429                 for (unsigned int j = 0; j < grid[i].size(); j++)
00430                 {
00431                         grid[i][j] = 0;
00432                 }
00433         }
00434         
00435         std::ifstream fin(p_filename.c_str());
00436         std::string buffer;
00437         std::vector<std::string> values;
00438         //initialize random generator
00439         srand(GetTickCount());
00440         while (fin.good()) {
00441                 std::getline(fin,buffer,'\n');
00442                 splitLine(values, buffer, ";");
00443                 if (values.size() >= 6)
00444                 {
00445                         unsigned int i = atoi(values[0].c_str()) - 1;
00446                         unsigned int j = atoi(values[1].c_str()) - 1;
00447                         grid[i][j] = new Field();
00448                         grid[i][j]->xCoord = i;
00449                         grid[i][j]->yCoord = j;
00450                         double green = atof(values[2].c_str());
00451                         double yellow = atof(values[3].c_str());
00452                         double red = atof(values[4].c_str());
00453                         double grey = atof(values[5].c_str());
00454                         double randEnergy = rand() / (double)RAND_MAX;
00455                         if (green > randEnergy)
00456                                 grid[i][j]->energy = 15;
00457                         else if (green + yellow > randEnergy)
00458                                 grid[i][j]->energy = 10;
00459                         else if (green + yellow + red > randEnergy)
00460                                 grid[i][j]->energy = 5;
00461                         else
00462                                 grid[i][j]->energy = 0;
00463                         if (values.size() >= 7) // maybe settlerange
00464                                 if (values[6] == "SR")
00465                                         grid[i][j]->isSettleRange = true;
00466                         if (values.size() == 9) //an unit is placed here
00467                         {
00468                                 std::string unitName = values[7];
00469                                 std::string playerName = values[8];
00470                                 //check if player exists
00471                                 if (players.find(playerName) == players.end())
00472                                 {
00473                                         players[playerName] = new Player(playerName);
00474                                 }
00475                                 grid[i][j]->unit = new Unit(players[playerName]);
00476                                 grid[i][j]->unit->load("units//" + unitName);
00477                         }
00478                 }
00479         }
00480         fin.close();
00481 
00482         Field::shadowTexture = new Object();
00483         Field::shadowTexture->loadAndBind("textures//shadow.png");
00484 
00485         return ret;
00486 }
00487 
00488 int Level::init()
00489 {
00490         int ret = 0;
00491 
00492         int maxI = -1;
00493         int maxJ = -1;
00494 
00495         //Load all Textures
00496         for (int i = 0; i < (int) grid.size(); i++)
00497         {
00498                 for (int j = 0; j < (int) grid[i].size(); j++)
00499                 {
00500                         if (grid[i][j] != 0)
00501                         {
00502                                 grid[i][j]->select("textures//plant.png");
00503                                 if (i > maxI)
00504                                         maxI = i;
00505                                 if (j > maxJ)
00506                                         maxJ = j;
00507                         }
00508                 }
00509         }
00510 
00511         position = Vector3d(-(maxI / 2.0) * 0.75, -(maxJ /2.0) * 0.87 - 0.44, 25.0);
00512 
00513         return ret;
00514 }
00515 
00516 int Level::initGL()
00517 {
00518         int ret = 0;
00519 
00520         ret = GLInterface::initGL();
00521 
00522         return ret;
00523 }
00524 
00525 int Level::pick()
00526 {
00527         int x = window->mousePos.x;
00528         int y = window->mousePos.y;
00529         int halfWidth = (int)(window->width / 2.0);
00530         int ret = 0;
00531         //check if the interface or the playingfield has been clicked
00532         bool checkInterface =   ((x >= halfWidth - (interfaceSizeWidth / 2))
00533                                                         && (x <= halfWidth + (interfaceSizeWidth / 2)) 
00534                                                         && (y <= interfaceSizeHeight));
00535 
00536         GLuint buff[256] = {0};
00537         GLint hits, view[4];
00538 
00539         //set everything
00540         if (checkInterface)
00541         {
00542                 setViewportInterface();
00543                 initViewInterface();
00544         }
00545         else
00546         {
00547                 setViewportCamera();
00548                 initViewCamera();
00549         }
00550 
00551         //This choose the buffer where store the values for the selection data
00552         glSelectBuffer(256, buff);
00553  
00554         //This retrieve info about the viewport
00555         glGetIntegerv(GL_VIEWPORT, view);
00556 
00557         // Switching in selecton mode
00558         glRenderMode(GL_SELECT);
00559 
00560         // Clearing the name's stack - This stack contains all the info about the objects
00561         glInitNames();
00562  
00563         // Now fill the stack with one element (or glLoadName will generate an error)
00564         glPushName(0);
00565  
00566         // Now modify the vieving volume, restricting selection area around the cursor*/
00567         glMatrixMode(GL_PROJECTION);
00568         glPushMatrix();
00569                 glLoadIdentity();
00570  
00571                 // restrict the draw to an area around the cursor
00572                 gluPickMatrix(x, y, 1.0, 1.0, view);
00573 
00574                 if (checkInterface)
00575                 {
00576                         initViewInterface(false);
00577                         
00578                         // draw only the names in the stack, and fill the array
00579                         renderInterface();
00580                 }
00581                 else
00582                 {
00583                         initViewCamera(false);
00584                         
00585                         // draw only the names in the stack, and fill the array
00586                         renderScene(false);
00587                 }
00588  
00589                 // Do you remeber? We do pushMatrix in PROJECTION mode
00590                 glMatrixMode(GL_PROJECTION);
00591         glPopMatrix();
00592  
00593         // get number of objects drawed in that area - and return to render mode
00594         hits = glRenderMode(GL_RENDER);
00595  
00596 
00597         glMatrixMode(GL_MODELVIEW);
00598 
00599 
00600         //ow select the lowest id, as it marks the field:
00601         if (hits > 0)
00602         {
00603                 ret = 1000000;
00604                 for (int i = 0; i < hits; i++)
00605                 {
00606                         if (ret > (GLubyte)buff[i * 4 + 3])
00607                                 ret = (GLubyte)buff[i * 4 + 3];
00608                 }
00609         }
00610         return ret;
00611 }
00612 
00613 int Level::setViewportCamera ()
00614 {
00615         int ret = 0;
00616         
00617         glViewport(0, 0, window->width, window->height);
00618         
00619         return ret;
00620 }
00621 
00622 int Level::setViewportInterface ()
00623 {
00624         int ret = 0;
00625 
00626         int halfWidth = (int)(window->width / 2.0);
00627 
00628         glViewport(halfWidth - (interfaceSizeWidth / 2), 0, interfaceSizeWidth, interfaceSizeHeight);
00629 
00630         return ret;
00631 }

Generated on Tue Jul 17 22:02:22 2007 for C0re by  doxygen 1.5.2