void MapGenerator::fillBSP(TCODBsp* root){ TCODBsp* temp = root; fillBox(temp->x,temp->y,temp->w,temp->h,"wall"); if (temp->isLeaf()){ std::cout<<temp->x<<", "<<temp->y<<"//"<<temp->w<<", "<<temp->h<<"\n"; int offset = RNG->getInt(1, 2); temp->x = (temp->x)+offset; temp->w = RNG->getInt((temp->w)-3,(temp->w)-(offset+1)); offset = RNG->getInt(1, 2); temp->y = (temp->y)+offset; temp->h = RNG->getInt((temp->h)-3,(temp->h)-(offset+1)); fillBox(temp->x,temp->y,temp->w,temp->h,"grnd"); } // fillBox(temp->x,temp->y,temp->w,temp->h,"grnd"); if (!temp->isLeaf()){ fillBSP(temp->getLeft()); fillBSP(temp->getRight()); connectBSP(temp); } }
void MapGenerator::genBSP(int numberLayers, int layerNumber){ if (layerNumber == 0){ fillBox(0,0,mapw,maph,"watr"); } else{ fillBox(0,0,mapw,maph,"watr"); } TCODBsp* myBSP = new TCODBsp(0,0,mapw, maph); int firstSplit = RNG->getInt(19,30); myBSP->splitOnce(false,firstSplit); TCODBsp *openSpace; TCODBsp *closedSpace; // if(firstSplit>39 ){// this is one of many possible configurations. using bsp, half open, half closed style level. // openSpace = myBSP->getLeft(); // closedSpace = myBSP->getRight(); //}else{ closedSpace = myBSP->getLeft(); openSpace = myBSP->getRight(); //} closedSpace->splitRecursive(NULL,4,8,8,1.8,1.4); openSpace->splitRecursive(NULL, 3,7 ,7,1.5,1.5); TCODBsp *temp = closedSpace; fillBSP(closedSpace); //connectBSP(closedSpace); myBSP->resize(0,0,mapw, maph); }
void MapGenerator::connectBSP(TCODBsp* root){ TCODBsp *temp = root; bool connectedRight; bool connectedLeft; int randNumOffset; int rightTry; int leftTry; if(!temp->horizontal){ randNumOffset = RNG->getInt(temp->getLeft()->y+1, (temp->getLeft()->y+temp->getLeft()->h)-2); rightTry = temp->getLeft()->x+temp->getLeft()->w; leftTry = rightTry; for(int p = 0; p<((temp->w)/4);p++){ stringMap[rightTry][randNumOffset].replace(0,4,"cgrs");//check before replacing in case it fails stringMap[leftTry][randNumOffset].replace(0,4,"cgrs"); //what if it's already in a room, surrounded by not wall? hmm if(numberSurrounding(rightTry, randNumOffset, "wall") < 3){ connectedRight = true; rightTry--; } if(numberSurrounding(leftTry, randNumOffset, "wall") < 3){ connectedLeft = true; leftTry++; } rightTry++; leftTry--; } } if(temp->horizontal){ randNumOffset = RNG->getInt(temp->getLeft()->x+1, (temp->getLeft()->x+temp->getLeft()->w)-2); rightTry = temp->getLeft()->y+temp->getLeft()->h; leftTry = rightTry; for(int p = 0; p<((temp->h)/4);p++){ stringMap[randNumOffset][rightTry].replace(0,4,"cgrs"); stringMap[randNumOffset][leftTry].replace(0,4,"cgrs"); //what if it's already in a room, surrounded by not wall? hmm if(numberSurrounding(randNumOffset, rightTry, "wall") < 3){ connectedRight = true; rightTry--; } if(numberSurrounding(randNumOffset, leftTry, "wall") < 3){ connectedLeft = true; leftTry++; } rightTry++; leftTry--; } } if (!connectedRight || !connectedLeft){ if(temp->horizontal){ for(int p = 0; p<((temp->w)/3);p++){ stringMap[randNumOffset][rightTry].replace(0,4,"wtsh "); stringMap[randNumOffset][leftTry].replace(0,4,"wtsh"); //what if it's already in a room, surrounded by not wall? hmm if(numberSurrounding(randNumOffset, rightTry, "wall") > 3){ rightTry--; } if(numberSurrounding(randNumOffset, leftTry, "wall") > 3){ leftTry++; } rightTry++; leftTry--; } } if(!temp->horizontal){ for(int p = 0; p<((temp->h)/3);p++){ stringMap[rightTry][randNumOffset].replace(0,4,"wtsh");//check before replacing in case it fails stringMap[leftTry][randNumOffset].replace(0,4,"wtsh"); //what if it's already in a room, surrounded by not wall? hmm if(numberSurrounding(rightTry+1, randNumOffset, "wall") > 3){ rightTry--; } if(numberSurrounding(leftTry-1, randNumOffset, "wall") > 3){ leftTry++; } rightTry++; leftTry--; } } connectBSP(root); } }
bool visitNode(TCODBsp* node, void* userdata) { dungeon_t* dungeon = (dungeon_t*) userdata; bool result = true; //TRACE("node.level=%d\n", node->level); if (node->isLeaf()) { int x = TCODRandom::getInstance()->getInt(node->x, node->x + (node->w - MIN_ROOM_W)); int y = TCODRandom::getInstance()->getInt(node->y, node->y + (node->h - MIN_ROOM_H)); int max_x = TCODRandom::getInstance()->getInt(x + MIN_ROOM_W, node->x + node->w); int max_y = TCODRandom::getInstance()->getInt(y + MIN_ROOM_H, node->y + node->h); int w = max_x - x; int h = max_y - y; _dig_room(dungeon, x + 1, y + 1, w - 1, h - 1); node->x = x + 1; node->y = y + 1; node->w = w - 1; node->h = h - 1; } else { TCODBsp* left = node->getLeft(); TCODBsp* right = node->getRight(); // Source and dest points for A*. int sx, sy, dx, dy; // Resize node to fit the two children. int min_x = min(left->x, right->x); int min_y = min(left->y, right->y); int max_x = max(left->x + left->w, right->x + right->w); int max_y = max(left->y + left->h, right->y + right->h); int w = max_x - min_x; int h = max_y - min_y; node->x = min_x; node->y = min_y; node->w = w; node->h = h; if (!left->isLeaf() || !right->isLeaf()) { coord_t left_coord, right_coord; do { left_coord = _get_random_position_of_tile_in_area(dungeon, TILES[TILE_DUMMY_WALL], left->x, left->y, left->w, left->h); right_coord = _get_random_position_of_tile_in_area(dungeon, TILES[TILE_DUMMY_WALL], right->x, right->y, right->w, right->h); } while (!_has_walkable_neighbour(dungeon, left_coord.x, left_coord.y) || !_has_walkable_neighbour(dungeon, right_coord.x, right_coord.y)); sx = left_coord.x; sy = left_coord.y; dx = right_coord.x; dy = right_coord.y; } else { // Pick a random point at a wall. if (node->horizontal) { if (left->y < right->y) { // Bottom wall of left room as src. sx = TCODRandom::getInstance()->getInt(left->x + 1, left->x + left->w - 2); sy = left->y + left->h - 1; // Top wall of right room as dst. dx = TCODRandom::getInstance()->getInt(right->x + 1, right->x + right->w - 2); dy = right->y; } else { // Top wall of left room as src. sx = TCODRandom::getInstance()->getInt(left->x + 1, left->x + left->w - 2); sy = left->y; // Bottom wall of right room as dst. dx = TCODRandom::getInstance()->getInt(right->x + 1, right->x + right->w - 2); dy = right->y + right->h - 1; } } else { if (left->x < right->x) { // Right wall of left room as src. sx = left->x + left->w - 1; sy = TCODRandom::getInstance()->getInt(left->y + 1, left->y + left->h - 2); // Left wall of right room as dst. dx = right->x; dy = TCODRandom::getInstance()->getInt(right->y + 1, right->y + right->h - 2); } else { // Left wall of left room as src. sx = left->x; sy = TCODRandom::getInstance()->getInt(left->y + 1, left->y + left->h - 2); // Right wall of right room as dst. dx = right->x + right->w - 1; dy = TCODRandom::getInstance()->getInt(right->y + 1, right->y + right->h - 2); } } } result = _dig_corridor(dungeon, sx, sy, dx, dy); } return result; }