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 }
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."); } } }