📄 dungeongenerator.cpp
字号:
scourge->getSDLHandler()->setHandlers((SDLEventHandler *)this, (SDLScreenView *)this); bool preGenerated = (locationIndex); locationIndex--; // generate the maze if(!preGenerated) { generateMaze(); // printMaze(); makeSparse(); // printMaze(); makeLoops(); // printMaze(); makeRooms(); // printMaze(); } else { constructMaze(locationIndex); } updateStatus(); // draw the nodes on the map drawNodesOnMap(map, shapePal, preGenerated, locationIndex); // hack: draw diff. floor tiles in HQ if(preGenerated) { for(Sint16 x = 0; x < MAP_WIDTH; x++) { for(Sint16 y = 0; y < MAP_DEPTH; y++) { if(map->getFloorPosition(x,y) == shapePal->findShapeByName("ROOM_FLOOR_TILE")) { map->setFloorPosition(x,y,shapePal->findShapeByName("ROOM2_FLOOR_TILE")); } } } } updateStatus();}void DungeonGenerator::drawNodesOnMap(Map *map, ShapePalette *shapePal, bool preGenerated, int locationIndex) { // add shapes to map Sint16 mapx, mapy; for(Sint16 x = 0; x < width; x++) { for(Sint16 y = 0; y < height; y++) { mapx = x * unitSide + offset; mapy = y * unitSide + offset; if(nodes[x][y] != UNVISITED) { if(nodes[x][y] >= ROOM) { map->setFloorPosition(mapx, mapy + unitSide, shapePal->findShapeByName("ROOM_FLOOR_TILE")); } else { map->setFloorPosition(mapx, mapy + unitSide, shapePal->findShapeByName("FLOOR_TILE")); } // init the free space if(nodes[x][y] & E_DOOR) { drawDoor(map, shapePal, mapx, mapy, E_DOOR); } else if(nodes[x][y] & W_DOOR) { drawDoor(map, shapePal, mapx, mapy, W_DOOR); } else if(nodes[x][y] & N_DOOR) { drawDoor(map, shapePal, mapx, mapy, N_DOOR); } else if(nodes[x][y] & S_DOOR) { drawDoor(map, shapePal, mapx, mapy, S_DOOR); } // random doors if((nodes[x][y] & W_PASS) && !(nodes[x][y] & N_PASS) && !(nodes[x][y] & S_PASS)) { if((int)(100.0 * rand()/RAND_MAX) <= randomDoors) drawDoor(map, shapePal, mapx, mapy, W_DOOR); } if((nodes[x][y] & E_PASS) && !(nodes[x][y] & N_PASS) && !(nodes[x][y] & S_PASS)) { if((int)(100.0 * rand()/RAND_MAX) <= randomDoors) drawDoor(map, shapePal, mapx, mapy, E_DOOR); } if((nodes[x][y] & S_PASS) && !(nodes[x][y] & W_PASS) && !(nodes[x][y] & E_PASS)) { if((int)(100.0 * rand()/RAND_MAX) <= randomDoors) drawDoor(map, shapePal, mapx, mapy, S_DOOR); } if((nodes[x][y] & N_PASS) && !(nodes[x][y] & W_PASS) && !(nodes[x][y] & E_PASS)) { if((int)(100.0 * rand()/RAND_MAX) <= randomDoors) drawDoor(map, shapePal, mapx, mapy, N_DOOR); } if(!(nodes[x][y] & W_PASS)) { if(nodes[x][y] & N_PASS && nodes[x][y] & S_PASS) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("EW_WALL_TWO_EXTRAS")); } else if(nodes[x][y] & N_PASS) { map->setPosition(mapx, mapy + unitSide - unitOffset, 0, shapePal->findShapeByName("EW_WALL_EXTRA")); } else if(nodes[x][y] & S_PASS) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("EW_WALL_EXTRA")); } else { map->setPosition(mapx, mapy + unitSide - unitOffset, 0, shapePal->findShapeByName("EW_WALL")); } if((int) (100.0 * rand()/RAND_MAX) <= torches) { map->setPosition(mapx + unitOffset, mapy + unitSide - 4, 6, shapePal->findShapeByName("LAMP_WEST")); map->setPosition(mapx + unitOffset, mapy + unitSide - 4, 4, shapePal->findShapeByName("LAMP_BASE")); } } if(!(nodes[x][y] & E_PASS)) { if(nodes[x][y] & N_PASS && nodes[x][y] & S_PASS) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("EW_WALL_TWO_EXTRAS")); } else if(nodes[x][y] & N_PASS) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide - unitOffset, 0, shapePal->findShapeByName("EW_WALL_EXTRA")); } else if(nodes[x][y] & S_PASS) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("EW_WALL_EXTRA")); } else { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide - unitOffset, 0, shapePal->findShapeByName("EW_WALL")); } if((int) (100.0 * rand()/RAND_MAX) <= torches) { map->setPosition(mapx + unitSide - (unitOffset + 1), mapy + unitSide - 4, 6, shapePal->findShapeByName("LAMP_EAST")); map->setPosition(mapx + unitSide - (unitOffset + 1), mapy + unitSide - 4, 4, shapePal->findShapeByName("LAMP_BASE")); } } if(!(nodes[x][y] & N_PASS)) { if(nodes[x][y] & W_PASS && nodes[x][y] & E_PASS) { map->setPosition(mapx, mapy + unitOffset, 0, shapePal->findShapeByName("NS_WALL_TWO_EXTRAS")); } else if(nodes[x][y] & W_PASS) { map->setPosition(mapx, mapy + unitOffset, 0, shapePal->findShapeByName("NS_WALL_EXTRA")); } else if(nodes[x][y] & E_PASS) { map->setPosition(mapx + unitOffset, mapy + unitOffset, 0, shapePal->findShapeByName("NS_WALL_EXTRA")); } else { map->setPosition(mapx + unitOffset, mapy + unitOffset, 0, shapePal->findShapeByName("NS_WALL")); } if((int) (100.0 * rand()/RAND_MAX) <= torches) { map->setPosition(mapx + 4, mapy + unitOffset + 1, 6, shapePal->findShapeByName("LAMP_NORTH")); map->setPosition(mapx + 4, mapy + unitOffset + 1, 4, shapePal->findShapeByName("LAMP_BASE")); } } if(!(nodes[x][y] & S_PASS)) { if(nodes[x][y] & W_PASS && nodes[x][y] & E_PASS) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("NS_WALL_TWO_EXTRAS")); } else if(nodes[x][y] & W_PASS) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("NS_WALL_EXTRA")); } else if(nodes[x][y] & E_PASS) { map->setPosition(mapx + unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("NS_WALL_EXTRA")); } else { map->setPosition(mapx + unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("NS_WALL")); } } if(nodes[x][y] & N_PASS && nodes[x][y] & W_PASS) { map->setPosition(mapx, mapy + unitOffset, 0, shapePal->findShapeByName("CORNER")); } if(nodes[x][y] & N_PASS && nodes[x][y] & E_PASS) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitOffset, 0, shapePal->findShapeByName("CORNER")); } if(nodes[x][y] & S_PASS && nodes[x][y] & W_PASS) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("CORNER")); } if(nodes[x][y] & S_PASS && nodes[x][y] & E_PASS) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("CORNER")); } if(!(nodes[x][y] & N_PASS) && !(nodes[x][y] & W_PASS)) { map->setPosition(mapx, mapy + unitOffset, 0, shapePal->findShapeByName("CORNER")); } if(!(nodes[x][y] & N_PASS) && !(nodes[x][y] & E_PASS)) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitOffset, 0, shapePal->findShapeByName("CORNER")); } if(!(nodes[x][y] & S_PASS) && !(nodes[x][y] & W_PASS)) { map->setPosition(mapx, mapy + unitSide, 0, shapePal->findShapeByName("CORNER")); } if(!(nodes[x][y] & S_PASS) && !(nodes[x][y] & E_PASS)) { map->setPosition(mapx + unitSide - unitOffset, mapy + unitSide, 0, shapePal->findShapeByName("CORNER")); } } } } updateStatus(); // Remove 'columns' from rooms for(int x = 0; x < MAP_WIDTH - unitSide; x++) { for(int y = 0; y < MAP_DEPTH - (unitSide * 2); y++) { if(map->getFloorPosition(x, y + unitSide) == shapePal->findShapeByName("ROOM_FLOOR_TILE") && map->getFloorPosition(x + unitSide, y + unitSide) == shapePal->findShapeByName("ROOM_FLOOR_TILE") && map->getFloorPosition(x, y + unitSide + unitSide) == shapePal->findShapeByName("ROOM_FLOOR_TILE") && map->getFloorPosition(x + unitSide, y + unitSide + unitSide) == shapePal->findShapeByName("ROOM_FLOOR_TILE")) { // map->setFloorPosition(x, y + unitSide, shapePal->findShapeByName("FLOOR_TILE")); map->removePosition(x + unitSide - unitOffset, y + unitSide, 0); map->removePosition(x + unitSide - unitOffset, y + unitSide + unitOffset, 0); map->removePosition(x + unitSide, y + unitSide, 0); map->removePosition(x + unitSide, y + unitSide + unitOffset, 0); } } } updateStatus(); int x, y; RpgItem *rpgItem; // add the containers for(int i = 0; i < roomCount; i++) { if(preGenerated && location[locationIndex].roomDimension[i][4] == 0) continue; for(int pos = unitOffset; pos < room[i].h * unitSide; pos++) { rpgItem = RpgItem::getRandomContainer(); if(rpgItem) { // WEST side x = (room[i].x * unitSide) + unitOffset + offset; y = (room[i].y * unitSide) + pos + offset; Shape *shape = scourge->getShapePalette()->getShape(rpgItem->getShapeIndex()); if(map->shapeFits(shape, x, y, 0) && !coversDoor(map, shapePal, shape, x, y)) { addItem(map, NULL, scourge->newItem(rpgItem), NULL, x, y); } } rpgItem = RpgItem::getRandomContainer(); if(rpgItem) { // EAST side x = ((room[i].x + room[i].w - 1) * unitSide) + unitSide - (unitOffset * 2) + offset; Shape *shape = scourge->getShapePalette()->getShape(rpgItem->getShapeIndex()); if(map->shapeFits(shape, x, y, 0) && !coversDoor(map, shapePal, shape, x, y)) { addItem(map, NULL, scourge->newItem(rpgItem), NULL, x, y); } } } for(int pos = unitOffset; pos < room[i].w * unitSide; pos++) { rpgItem = RpgItem::getRandomContainerNS(); if(rpgItem) { // NORTH side x = (room[i].x * unitSide) + pos + offset; y = (room[i].y * unitSide) + (unitOffset * 2) + offset; Shape *shape = scourge->getShapePalette()->getShape(rpgItem->getShapeIndex()); if(map->shapeFits(shape, x, y, 0) && !coversDoor(map, shapePal, shape, x, y)) { addItem(map, NULL, scourge->newItem(rpgItem), NULL, x, y); } } rpgItem = RpgItem::getRandomContainerNS(); if(rpgItem) { // SOUTH side y = ((room[i].y + room[i].h - 1) * unitSide) + unitSide - unitOffset + offset; Shape *shape = scourge->getShapePalette()->getShape(rpgItem->getShapeIndex()); if(map->shapeFits(shape, x, y, 0) && !coversDoor(map, shapePal, shape, x, y)) { addItem(map, NULL, scourge->newItem(rpgItem), NULL, x, y); } } } } updateStatus(); // Collapse the free space and put objects in the available spots ff = (Sint16*)malloc( 2 * sizeof(Sint16) * MAP_WIDTH * MAP_DEPTH ); if(!ff) { fprintf(stderr, "out of mem\n"); exit(0); } ffCount = 0; for(int fx = offset; fx < MAP_WIDTH; fx+=unitSide) { for(int fy = offset; fy < MAP_DEPTH; fy+=unitSide) { if(map->getFloorPosition(fx, fy + unitSide)) { for(int ffx = 0; ffx < unitSide; ffx++) { for(int ffy = unitSide; ffy > 0; ffy--) { if(!map->getLocation(fx + ffx, fy + ffy, 0)) { *(ff + ffCount * 2) = fx + ffx; *(ff + ffCount * 2 + 1) = fy + ffy; ffCount++; } } } } } } updateStatus(); // add stairs for multi-level missions if(!preGenerated) { if(stairsUp) { bool done = false; for(int i = 0; i < 10; i++) { Shape *shape = scourge->getShapePalette()->findShapeByName("GATE_UP"); bool fits = getLocationInRoom(map, i, shape, &x, &y); if(fits && !coversDoor(map, scourge->getShapePalette(), shape, x, y)) { addItem(map, NULL, NULL, shape, x, y); done = true; break; } } if(!done) { cerr << "Error: couldn't add up stairs." << endl; exit(1); } } if(stairsDown) { bool done = false; for(int i = 0; i < 10; i++) { Shape *shape = scourge->getShapePalette()->findShapeByName("GATE_DOWN"); bool fits = getLocationInRoom(map, i, shape, &x, &y); if(fits && !coversDoor(map, scourge->getShapePalette(), shape, x, y)) { addItem(map, NULL, NULL, shape, x, y); done = true; break; } } if(!done) { cerr << "Error: couldn't add down stairs." << endl; exit(1); } } } updateStatus(); // add pre-generated shapes first if(preGenerated) { for(int i = 0; i < location[locationIndex].shapeCount; i++) { int mapx = location[locationIndex].shapePosition[i].x + offset; int mapy = location[locationIndex].shapePosition[i].y + offset; map->setPosition(mapx, mapy, location[locationIndex].shapePosition[i].z, shapePal->findShapeByName(location[locationIndex].shapePosition[i].name)); // find and remove this location from ff list (replace w. last entry and decr. counter) for(int n = 0; n < ffCount; n++) { if(mapx == ff[n * 2] && mapy == ff[n * 2 + 1]) { ff[n * 2] = ff[(ffCount - 1) * 2]; ff[n * 2 + 1] = ff[(ffCount - 1) * 2 + 1]; ffCount--; break; } } } } updateStatus(); if(!preGenerated) { // add the items for(int i = 0; i < objectCount; i++) { RpgItem *rpgItem = RpgItem::getRandomItem(level); if(!rpgItem) { cerr << "Warning: no items defined for level: " << level << endl; break; } Item *item = scourge->newItem(rpgItem); getRandomLocation(map, item->getShape(), &x, &y); addItem(map, NULL, item, NULL, x, y); } // add mission objects if(mission && mission->getObjective() && !stairsDown) { // mission objects are on a pedestal // and make them blocking so creatures can't get them for(int i = 0; i < mission->getObjective()->itemCount; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -