bool CRoomManager::init() { // register to console: TODO register some usefull stuff CV_GAME_MANAGER->getConsole()->registerClass(this,"ROOM MANAGER"); CV_GAME_MANAGER->getConsole()->addParam(RLROOM,"() Reloads the rooms."); CV_GAME_MANAGER->getConsole()->addParam(RC,"() Prints room count."); CV_GAME_MANAGER->getConsole()->addParam(RC,"() Prints room count."); CV_GAME_MANAGER->getConsole()->addParam(SRA,"() Shows room area."); // construct new rooms CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); for (GLuint y=0; y<CV_LEVEL_MAP_SIZE; y++) { for (GLuint x=0; x<CV_LEVEL_MAP_SIZE; x++) { CBlock *block = lManager->getBlock(x,y); if (block->isRoom() && !block->isInRoom()) { if(block->getType() == CV_BLOCK_TYPE_HEART_ID && block->getOwner() == CV_PLAYER_0) { cml::vector3f position = block->getRealPosition(); CV_GAME_MANAGER->getControlManager()->getCamera()->setPosition(cml::vector3f(position[0]+0.3, CV_CAMERA_INITIAL_HEIGHT, position[2]+1)); } // we found a room tile that isn't in a room yet. we create a new room. CRoom *newRoom = new CRoom(); newRoom->init(block); allRooms[newRoom->getIndex()] = newRoom; roomColors[newRoom->getIndex()] = vector3f((GLfloat)(rand()%101)/100.0f,(GLfloat)(rand()%101)/100.0f,(GLfloat)(rand()%101)/100.0f); } } } return true; }
GLvoid CRoom::rec(vector2i pos) { // check pos validity if (pos[0]<0 || pos[1]<0 || pos[0]>=CV_LEVEL_MAP_SIZE || pos[1]>=CV_LEVEL_MAP_SIZE) { return; } CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); CBlock *baseBlock = roomTiles.size()>0?*roomTiles.begin():NULL; CBlock *targetBlock = lManager->getBlock(pos); // check if we are of same type and owner as last block if (baseBlock && !lManager->isSameTypeAndOwner(pos[0],pos[1],baseBlock)) { return; } // check if we have already been here if (targetBlock->isInRoom()) { return; } // we have a valid block to add to out room targetBlock->setRoomIndex(roomIndex); roomTiles.push_back(targetBlock); // search in all directions rec(pos+vector2i(-1,0)); // L rec(pos+vector2i(+1,0)); // R rec(pos+vector2i(0,-1)); // U rec(pos+vector2i(0,+1)); // D }
GLint CBlock::getFreeFaces(GLint faces[4]) { GLint cnt = 0; if (isLow()) { // a special type of light. could be described as a torch in the air. return -1; } CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); if (lManager->getBlock(logicalPosition+vector2i(0,1))->isLow()) { faces[cnt++]=BFS_FRONT; } if (lManager->getBlock(logicalPosition+vector2i(0,-1))->isLow()) { faces[cnt++]=BFS_BACK; } if (lManager->getBlock(logicalPosition+vector2i(1,0))->isLow()) { faces[cnt++]=BFS_LEFT; } if (lManager->getBlock(logicalPosition+vector2i(-1,0))->isLow()) { faces[cnt++]=BFS_RIGHT; } return cnt; }
GLvoid CBlock::finalize() { CV_GAME_MANAGER->getBlockManager()->generateBlockGeometry(this); // now that we have the geometry we can calculate bounding box // TODO: in release an exact bbox should be calculated?? boundingBox.reset(); boundingBox.update(vertices[BFS_FRONT]); boundingBox.update(vertices[BFS_BACK]); boundingBox.update(vertices[BFS_LEFT]); boundingBox.update(vertices[BFS_RIGHT]); boundingBox.update(vertices[BFS_TOP]); boundingBox.update(vertices[BFS_WATER_LAVA]); boundingBox.update(vector3f(vertices[BFS_TOP][0],CV_BLOCK_HEIGHT*4.0f,vertices[BFS_TOP][2])); // ceiling can be pretty high boundingBox.calculateExtents(); boundingBox.calculateVertices(); // init the skip flags if (lava||water) { CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); GLint mapX = logicalPosition[0]; GLint mapY = logicalPosition[1]; GLint ltype = lManager->getBlockType(mapX-1,mapY); GLint rtype = lManager->getBlockType(mapX+1,mapY); GLint utype = lManager->getBlockType(mapX,mapY-1); GLint dtype = lManager->getBlockType(mapX,mapY+1); GLint lutype = lManager->getBlockType(mapX-1,mapY-1); GLint ldtype = lManager->getBlockType(mapX-1,mapY+1); GLint rutype = lManager->getBlockType(mapX+1,mapY-1); GLint rdtype = lManager->getBlockType(mapX+1,mapY+1); bool l = (ltype==CV_BLOCK_TYPE_LAVA_ID || ltype==CV_BLOCK_TYPE_WATER_ID); bool r = (rtype==CV_BLOCK_TYPE_LAVA_ID || rtype==CV_BLOCK_TYPE_WATER_ID); bool u = (utype==CV_BLOCK_TYPE_LAVA_ID || utype==CV_BLOCK_TYPE_WATER_ID); bool d = (dtype==CV_BLOCK_TYPE_LAVA_ID || dtype==CV_BLOCK_TYPE_WATER_ID); bool lu = (lutype==CV_BLOCK_TYPE_LAVA_ID || lutype==CV_BLOCK_TYPE_WATER_ID); bool ru = (rutype==CV_BLOCK_TYPE_LAVA_ID || rutype==CV_BLOCK_TYPE_WATER_ID); bool ld = (ldtype==CV_BLOCK_TYPE_LAVA_ID || ldtype==CV_BLOCK_TYPE_WATER_ID); bool rd = (rdtype==CV_BLOCK_TYPE_LAVA_ID || rdtype==CV_BLOCK_TYPE_WATER_ID); for (GLint i=0; i<4; i++) { ZeroMemory(skip[i],sizeof(bool)*4); } skip[0][0]=skip[1][0]=skip[2][0]=skip[3][0]=!l; skip[0][3]=skip[1][3]=skip[2][3]=skip[3][3]=!r; skip[0][0]=skip[0][1]=skip[0][2]=skip[0][3]=!u; skip[3][0]=skip[3][1]=skip[3][2]=skip[3][3]=!d; skip[0][0]=!l||!u||!lu; skip[0][3]=!r||!u||!ru; skip[3][3]=!r||!d||!rd; skip[3][0]=!l||!d||!ld; } finalized = true; }
GLint CBlock::getEdgeSubtiles(GLint subtiles[]) { /* _____________ |0 |1 |2 | ly2 |___|___|___| |3 |4 |5 | ly1 |___|___|___| |6 |7 |8 | ly0 |___|___|___| lx0 lx1 lx2 */ GLint arrayPos=0; CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); GLint mapX = logicalPosition[0]; GLint mapY = logicalPosition[1]; if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX-1,mapY,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY-1,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX-1,mapY-1,this)) { subtiles[arrayPos++]=0; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY-1,this)) { subtiles[arrayPos++]=1; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX+1,mapY,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY-1,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX+1,mapY-1,this)) { subtiles[arrayPos++]=2; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX-1,mapY,this)) { subtiles[arrayPos++]=3; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX+1,mapY,this)) { subtiles[arrayPos++]=5; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX-1,mapY,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY+1,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX-1,mapY+1,this)) { subtiles[arrayPos++]=6; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY+1,this)) { subtiles[arrayPos++]=7; } if (lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX+1,mapY,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX,mapY+1,this) || lManager->isNotSameTypeAndOwnerAndNotRockOrEarth(mapX+1,mapY+1,this)) { subtiles[arrayPos++]=8; } return arrayPos; }
bool CPathManager1::findPath(GLint startX, GLint startY, GLint endX, GLint endY, std::vector<cml::vector2i> *path) { int xCnt, yCnt; int ParentX, ParentY; cellData PathMap[85][85]; //Make sure the starting point and ending point are not the same if((startX == endX) && (startY == endY)) return true; CLevelManager *lvlMan = CV_GAME_MANAGER->getLevelManager(); //Make sure the starting/ending point is not a wall if(!lvlMan->getBlock(startX,startY)->isLow()) return false; //Set the flags bool PathFound = false; bool PathHunt = true; //Put the starting point on the open list for(yCnt=0;yCnt<85;yCnt++) { for(xCnt=0;xCnt<85;xCnt++) { PathMap[xCnt][yCnt].FCost=0; PathMap[xCnt][yCnt].GCost=0; PathMap[xCnt][yCnt].HCost=0; PathMap[xCnt][yCnt].OCList=0; PathMap[xCnt][yCnt].Parent[0]=0; PathMap[xCnt][yCnt].Parent[1]=0; } } Heap.ResetHeap(); PathMap[startX][startY].OCList = inOpened; Heap.Add(0, startX, startY); //Find the children while(PathHunt) { if(Heap.Count() != 0) { //Get the parent node ParentX = Heap.GetX(); ParentY = Heap.GetY(); //Remove the root PathMap[ParentX][ParentY].OCList = inClosed; Heap.RemoveRoot(); //Find the available children to add to the open list for(yCnt=ParentY - 1;yCnt<=ParentY + 1;yCnt+=1) { for(xCnt=ParentX - 1;xCnt<=ParentX + 1;xCnt+=1) { //Make sure we are not out of bounds if(xCnt != -1 && xCnt != 85 + 1 && yCnt != -1 && yCnt <= 85) { //Make sure it's not on the closed list if(PathMap[xCnt][yCnt].OCList != inClosed) { //Make sure no wall if(lvlMan->getBlock(xCnt,yCnt)->isWalkable(false) || (xCnt == endX && yCnt == endY)) { //Don't cut across corners bool CanWalk = true; if(xCnt == ParentX - 1) { if(yCnt == ParentY - 1) { if(!lvlMan->getBlock(ParentX - 1,ParentY)->isWalkable(false) || !lvlMan->getBlock(ParentX,ParentY - 1)->isWalkable(false)) CanWalk = false; } else if(yCnt == ParentY + 1) { if(!lvlMan->getBlock(ParentX,ParentY + 1)->isWalkable(false) || !lvlMan->getBlock(ParentX - 1,ParentY)->isWalkable(false)) CanWalk = false; } } else if(xCnt == ParentX + 1) { if(yCnt == ParentY - 1) { if(!lvlMan->getBlock(ParentX,ParentY - 1)->isWalkable(false) || !lvlMan->getBlock(ParentX + 1,ParentY)->isWalkable(false)) CanWalk = false; } else if(yCnt == ParentY + 1) { if(!lvlMan->getBlock(ParentX + 1,ParentY)->isWalkable(false) || !lvlMan->getBlock(ParentX,ParentY + 1)->isWalkable(false)) CanWalk = false; } } //If we can move this way if(CanWalk) { if(PathMap[xCnt][yCnt].OCList != inOpened) { //Calculate the GCost if(std::abs(xCnt - ParentX) == 1 && std::abs(yCnt - ParentY) == 1) PathMap[xCnt][yCnt].GCost = PathMap[ParentX][ParentY].GCost + 14; else PathMap[xCnt][yCnt].GCost = PathMap[ParentX][ParentY].GCost + 10; //Calculate the HCost PathMap[xCnt][yCnt].HCost = 10 * (std::abs(xCnt - endX) + std::abs(yCnt - endY)); PathMap[xCnt][yCnt].FCost = (PathMap[xCnt][yCnt].GCost + PathMap[xCnt][yCnt].HCost); //Add the parent value PathMap[xCnt][yCnt].Parent[0] = ParentX; PathMap[xCnt][yCnt].Parent[1] = ParentY; //Add the item to the heap Heap.Add(PathMap[xCnt][yCnt].FCost, xCnt, yCnt); //Add the item to the open list PathMap[xCnt][yCnt].OCList = inOpened; } else { //We will check for better value int AddedGCost; if(std::abs(xCnt - ParentX) == 1 && std::abs(yCnt - ParentY) == 1) AddedGCost = 14; else AddedGCost = 10; int tempCost = PathMap[ParentX][ParentY].GCost + AddedGCost; if(tempCost < PathMap[xCnt][yCnt].GCost) { PathMap[xCnt][yCnt].GCost = tempCost; PathMap[xCnt][yCnt].Parent[0] = ParentX; PathMap[xCnt][yCnt].Parent[1] = ParentY; if(PathMap[xCnt][yCnt].OCList == inOpened) { int NewCost = PathMap[xCnt][yCnt].HCost + PathMap[xCnt][yCnt].GCost; Heap.Add(NewCost, xCnt, yCnt); } } } } } } } } } } else { PathFound = false; PathHunt = false; return false; } //If we find a path if(PathMap[endX][endY].OCList == inOpened) { PathFound = true; PathHunt = false; } } if(PathFound) { int tX = endX; int tY = endY; int sX; int sY; if(lvlMan->getBlock(tX,tY)->isLow()) path->push_back(cml::vector2i(tX,tY)); while(true) { sX = tX; sY = tY; path->push_back(PathMap[sX][sY].Parent); tX = PathMap[sX][sY].Parent[0]; tY = PathMap[sX][sY].Parent[1]; if(tX == startX && tY == startY) return true; } } return false; }
GLvoid CLightingManager::addLightSource(vector2i position, GLint lightSourceType) { // depending on the block position we need to setup from 1 to 4 lights CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); GLint faces[4]; GLint bfVis = lManager->getBlock(position)->getFreeFaces(faces); vector3f lPoss[] = { vector3f(CV_BLOCK_WIDTH/2,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH+CV_BLOCK_DEPTH/10.0f), // front vector3f(CV_BLOCK_WIDTH/2,CV_BLOCK_HEIGHT,-CV_BLOCK_DEPTH/10.0f), // back vector3f(CV_BLOCK_WIDTH+CV_BLOCK_DEPTH/10.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f), // left vector3f(-CV_BLOCK_DEPTH/10.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f), // right vector3f(CV_BLOCK_DEPTH/2.0f,CV_BLOCK_HEIGHT,CV_BLOCK_DEPTH/2.0f) // middle }; if (bfVis==-1) { bfVis=1; faces[0]=4; } for (GLint i=0; i<bfVis; i++) { // get a light from the light pool //CLightSource *light = lightSourcePool[lightSourceType].popObject(); CLightSource *light = new CLightSource(lightIndexName[lightSourceType]); if (light) { // set its position light->setPosition(lManager->getBlock(position)->getRealPosition()+lPoss[faces[i]]); // append to block //blockLightData[position[1]][position[0]].add(light); //blockLightData[position[1]][position[0]].add(light,lManager->getBlock(position)); // and add to the global list of used lights lightSources.push_back(light); GLint lightRadius = (int)ceil(light->getRadius()/CV_BLOCK_WIDTH)+2; // +2 is there for extended radius comparison //vector2i lightPos = CConversions::realToLogical(light->getPosition()); // now for every block of this light, add references of this light to influenced neighbour blocks. for (GLint y=-lightRadius; y<=lightRadius; y++) { for (GLint x=-lightRadius; x<=lightRadius; x++) { if (position[1]+y<0 || position[0]+x<0 || position[1]+y>=84 || position[0]+x>=84) { continue; } if (faces[i]==CBlock::BFS_FRONT && y<0) { continue; } if (faces[i]==CBlock::BFS_BACK && y>0) { continue; } if (faces[i]==CBlock::BFS_LEFT && x<0) { continue; } if (faces[i]==CBlock::BFS_RIGHT && x>0) { continue; } CBlock *block = lManager->getBlock(position[0]+x,position[1]+y); vector3f lPos(light->getPosition()[0],0.0f,light->getPosition()[2]); GLfloat d1 = (block->getRealPosition()-lPos).length(); GLfloat d2 = ((block->getRealPosition()+vector3f(CV_BLOCK_WIDTH,0.0f,0.0f))-lPos).length(); GLfloat d3 = ((block->getRealPosition()+vector3f(CV_BLOCK_WIDTH,0.0f,CV_BLOCK_DEPTH))-lPos).length(); GLfloat d4 = ((block->getRealPosition()+vector3f(0.0f,0.0f,CV_BLOCK_DEPTH))-lPos).length(); GLfloat rad =light->getRadius(); if (d1<=rad || d2<=rad || d3<=rad || d4<=rad) { blockLightData[position[1]+y][position[0]+x].add(light,block); } } } } } }
bool CRenderManager::update() { glColor3f(1.0f,1.0f,1.0f); // get camera CCamera *camera = CV_GAME_MANAGER->getControlManager()->getCamera(); // transform view camera->transformView(); // Draw the map and items that fall into view frustum. // 1. extract approximate logical location of camera in the level map. vector2i center = CConversions::realToLogical(camera->getPosition()); GLint centerX = center[0]; GLint centerY = center[1]; bool isFPS = CV_GAME_MANAGER->getControlManager()->isFPS(); if (isFPS) { // fog only in FPS mode glEnable(GL_FOG); } /* In FPS mode we can't use height to determine visible offset. We have to use some extent read from config (CV_CAMERA_FPS_EXTENT). */ GLint diff = (GLint)(isFPS?cameraFPSExtent:camera->getPosition()[1]*10.0f); // 2. create a bounding square making its center logical position calculate above. GLint minX = (centerX-diff>=0?centerX-diff:0); GLint minY = (centerY-diff>=0?centerY-diff:0); GLint maxX = (centerX+diff<(GLint)CV_LEVEL_MAP_SIZE?centerX+diff:CV_LEVEL_MAP_SIZE-1); GLint maxY = (centerY+diff<(GLint)CV_LEVEL_MAP_SIZE?centerY+diff:CV_LEVEL_MAP_SIZE-1); // 3. go through all block that fall into this bounding square and check if they fall // int out view frustum. If not then just exclude them. CBlock *block; GLint blockVisible = 0, allVerticesCount = 0, creaturesVisible = 0, maxVertInput = 0, maxTexInput = 0; tmpVboVertexBufferSize = 0; tmpVboTexCoordBufferSize = 0; vector3f vertA, vertB, vertC; GLfloat **verts, *texCoords; CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); CAnimatedTerrainManager *atManager = CV_GAME_MANAGER->getAnimatedTerrainManager(); CFrustum *frustum = CV_GAME_MANAGER->getControlManager()->getViewFrustum(); bool lavaWater = false; GLfloat delta = CV_GAME_MANAGER->getDeltaTime(); renderedBlocks.clear(); for (GLint y=minY; y<=maxY; y++) { for (GLint x=minX; x<=maxX; x++) { block = lManager->getBlock(x,y); if (block) { //block->getBoundingBox()->draw(); // just for testing if (frustum->containsBBOX(block->getBoundingBox())) { blockVisible++; block->updateTexture(delta); lavaWater = (block->isLava() || block->isWater()); if (lavaWater) { atManager->updateBlock(block); } renderedBlocks.push_back(block); // draw block objects if (block->getBlockObjects()->size()>0) { for (std::vector<CBlockObject*>::iterator rmIter = block->getBlockObjects()->begin(); rmIter != block->getBlockObjects()->end(); rmIter++) { CBlockObject *bObj = *rmIter; bObj->moveTo(); glRotatef(bObj->getRotateY(),0.0f,1.0f,0.0f); bObj->drawModel(delta); glRotatef(-bObj->getRotateY(),0.0f,1.0f,0.0f); bObj->moveBack(); } } bool isRoom = block->isRoom(); if (isRoom) { std::vector<GLuint> *dls = block->getDisplayLists(); if (dls->size()!=0) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,textureAtlasColor); glBegin(GL_QUADS); { for (std::vector<GLuint>::iterator dlIter = dls->begin(); dlIter != dls->end(); dlIter++) { glCallList(*dlIter); } } glEnd(); glDisable(GL_TEXTURE_2D); } } for (GLint f=CBlock::BFS_FRONT; f<=CBlock::BFS_CEILING; f++) { if ((!isFPS && f==CBlock::BFS_CEILING) || (isFPS && f==CBlock::BFS_TOP) || (isRoom && f!=CBlock::BFS_CEILING)) { continue; } if (block->isFaceVisible((CBlock::BLOCK_FACE_SELECTOR)f)) { verts = block->getVertices(); texCoords = block->getTextureCoordinates((CBlock::BLOCK_FACE_SELECTOR)f); if (lavaWater && f<=CBlock::BFS_RIGHT) { /* Lava and water have only lowers row of wall sections drawn. If they are drawn at all. */ maxVertInput = CV_FBLR_W_L_FACE_VERT_FLOATS; maxTexInput = CV_FBLR_W_L_FACE_TEX_FLOATS; } else { maxVertInput = f>=CBlock::BFS_TOP?CV_TBWLC_FACE_VERT_FLOATS:CV_FBLR_FACE_VERT_FLOATS; maxTexInput = f>=CBlock::BFS_TOP?CV_TBWLC_FACE_TEX_FLOATS:CV_FBLR_FACE_TEX_FLOATS; } if (tmpVboVertexBufferSize+maxVertInput>CV_MAX_VERTEX_BUFFER*3) { vbo->setElementsCount(CVBO::IDT_vertex,tmpVboVertexBufferSize/3); vbo->setElementsCount(CVBO::IDT_texture0,tmpVboTexCoordBufferSize/2); vbo->setElementsCount(CVBO::IDT_texture1,tmpVboTexCoordBufferSize/2); vbo->draw(); allVerticesCount+=tmpVboVertexBufferSize; tmpVboVertexBufferSize=0; tmpVboTexCoordBufferSize=0; } memcpy(tmpVboVertexBuffer+tmpVboVertexBufferSize, verts[f], sizeof(GLfloat)*maxVertInput); tmpVboVertexBufferSize+=maxVertInput; memcpy(tmpVboTexCoordBuffer+tmpVboTexCoordBufferSize, texCoords, sizeof(GLfloat)*maxTexInput); tmpVboTexCoordBufferSize+=maxTexInput; } } } } } } if (tmpVboVertexBufferSize>0) { vbo->setElementsCount(CVBO::IDT_vertex,tmpVboVertexBufferSize/3); vbo->setElementsCount(CVBO::IDT_texture0,tmpVboTexCoordBufferSize/2); vbo->setElementsCount(CVBO::IDT_texture1,tmpVboTexCoordBufferSize/2); vbo->draw(); allVerticesCount+=tmpVboVertexBufferSize; } // draw creatures CCreatureManager *cManager = CV_GAME_MANAGER->getCreatureManager(); GLint cCount = cManager->getCreatureVector()->size(); if (cCount>0) { CCreature *creature = NULL; for (std::vector<CCreature*>::iterator cIter = cManager->getCreatureVector()->begin(); cIter != cManager->getCreatureVector()->end(); cIter++) { creature = (*cIter); if (creature) { sBoundingBox *cBBOX = creature->getModel()->getBoundingBox(); cBBOX->translate(creature->getPosition()); if (frustum->containsBBOX(cBBOX)) { creature->draw(delta); creaturesVisible++; } cBBOX->translate(-creature->getPosition()); } } } // draw transparent block objects for (std::vector<CBlock*>::iterator vbIter = renderedBlocks.begin(); vbIter != renderedBlocks.end(); vbIter++) { block = *vbIter; if (block->getBlockObjects()->size()>0) { for (std::vector<CBlockObject*>::iterator rmIter = block->getBlockObjects()->begin(); rmIter != block->getBlockObjects()->end(); rmIter++) { CBlockObject *bObj = *rmIter; bObj->moveTo(); glRotatef(bObj->getRotateY(),0.0f,1.0f,0.0f); bObj->drawEffect(); glRotatef(-bObj->getRotateY(),0.0f,1.0f,0.0f); bObj->moveBack(); } } } glDisable(GL_FOG); if (!isFPS) { handlePickedObjects(); } CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15*3),"Visible blocks: %d",blockVisible); CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15*2),"Visible creatures: %d",creaturesVisible); CV_GAME_MANAGER->getTextPrinter()->print((GLfloat)0,(GLfloat)(CV_SETTINGS_WINDOW_HEIGHT-15),"Triangles drawn: %d",(allVerticesCount/4)*2); // render the lights representations. usefull for debugging CV_GAME_MANAGER->getLightingManager()->drawLightSources(frustum); return true; }
GLvoid CRoomManager::addRoomTile(CBlock *block) { CLevelManager *lManager = CV_GAME_MANAGER->getLevelManager(); vector2i pos = block->getLogicalPosition(); vector2i posses[] = {vector2i(-1,0),vector2i(1,0),vector2i(0,-1),vector2i(0,1)}; bool nbrs[4]; nbrs[0] = lManager->isSameTypeAndOwner(pos[0]-1,pos[1],block); nbrs[1] = lManager->isSameTypeAndOwner(pos[0]+1,pos[1],block); nbrs[2] = lManager->isSameTypeAndOwner(pos[0],pos[1]-1,block); nbrs[3] = lManager->isSameTypeAndOwner(pos[0],pos[1]+1,block); GLint cnt = 0; cnt+=nbrs[0]?1:0; cnt+=nbrs[1]?1:0; cnt+=nbrs[2]?1:0; cnt+=nbrs[3]?1:0; if (cnt==0) { // create a new room CRoom *newRoom = new CRoom(); newRoom->getRoomTilesVector()->push_back(block); newRoom->reownTiles(); allRooms[newRoom->getIndex()] = newRoom; roomColors[newRoom->getIndex()] = vector3f((GLfloat)(rand()%101)/100.0f,(GLfloat)(rand()%101)/100.0f,(GLfloat)(rand()%101)/100.0f); CV_GAME_MANAGER->getConsole()->writeLine("A new room!"); } else { GLint owner = -1; GLint roomIndex = -1; GLint type = -1; bool set = false; bool ok[] = {true, true, true}; CBlock *testBlock = NULL; for (int i=0; i<4; i++) { if (nbrs[i]) { testBlock = lManager->getBlock(pos+posses[i]); if (!set) { set = true; owner = testBlock->getOwner(); roomIndex = testBlock->getRoomIndex(); type = testBlock->getType(); } else { ok[0] &= (owner == testBlock->getOwner()); ok[1] &= (roomIndex == testBlock->getRoomIndex()); ok[2] &= (type == testBlock->getType()); } } } if (ok[0]&&ok[1]&&ok[2]) { // all of same type, owner and room. just add this tile to this existing room allRooms[testBlock->getRoomIndex()]->getRoomTilesVector()->push_back(block); allRooms[testBlock->getRoomIndex()]->reownTiles(); CV_GAME_MANAGER->getConsole()->writeLine("Tile added to the existing room."); } else { std::map<GLint, CBlock*> blockPerRoom; // we must make some merging for (int i=0; i<4; i++) { if (nbrs[i]) { testBlock = lManager->getBlock(pos+posses[i]); blockPerRoom[testBlock->getRoomIndex()] = testBlock; } } // on this stage there are at least 2 elements in blockPerRoom. // take the first room and add it it all other room tiles. // then delete other rooms std::map<GLint, CBlock*>::iterator irIter = blockPerRoom.begin(); CRoom *targetRoom = allRooms[irIter->first]; irIter++; for (irIter; irIter!=blockPerRoom.end(); irIter++) { CRoom *room = allRooms[irIter->first]; for (GLuint t=0; t<room->getRoomTilesVector()->size(); t++) { targetRoom->getRoomTilesVector()->push_back((*room->getRoomTilesVector())[t]); } // delete the unwanted room allRooms.erase(allRooms.find(irIter->first)); } targetRoom->getRoomTilesVector()->push_back(block); targetRoom->reownTiles(); CV_GAME_MANAGER->getConsole()->writeLine("Rooms merged."); } } }