1 module dminer.core.generators; 2 3 import dminer.core.minetypes; 4 import dminer.core.blocks; 5 import dminer.core.world; 6 import dminer.core.terrain; 7 import dminer.core.chunk; 8 9 10 __gshared static short[] TERRAIN_INIT_DATA = [ 11 // V 12 10, 10, 10, 10, 30, 30, 30, 30, 30, 30, 30, 30, 10, 10, 10, 10, 10, 13 10, 10, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 20, 20, 20, 20, 10, 14 10, 20, 20, 50, 50, 150, 50, 50, 50, 50, 250, 50, 50, 50, 20, 20, 10, 15 10, 20, 50, 50, 50, 50, 50, 150, 50, 50, 50, 150, 50, 50, 50, 20, 10, 16 10, 50, 250, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 150, 50, 20, 30, 17 30, 50, 50, 50, 50, 50, 150, 50, 50, 50, 250, 50, 50, 50, 50, 50, 30, 18 30, 50, 50, 50, 50, 50, 50, 50, 100, 50, 50, 50, 80, 50, 250, 50, 30, 19 30, 50, 50, 50, 50, 50, 50, 110, 80, 130, 50, 50, 250, 50, 50, 50, 30, 20 30, 50, 50, 50, 50, 50, 150, 100, 50, 140, 50, 50, 50, 50, 50, 50, 30, // <== 21 30, 50, 50, 50, 50, 50, 50, 110, 40, 120, 50, 90, 50, 250, 50, 50, 30, 22 30, 50, 50, 50, 50, 150, 50, 50, 110, 50, 50, 50, 50, 50, 50, 50, 30, 23 30, 50, 50, 50, 50, 50, 150, 50, 50, 50, 150, 50, 150, 50, 50, 50, 10, 24 30, 50, 50, 50, 50, 50, 80, 50, 50, 150, 50, 50, 50, 50, 50, 50, 10, 25 30, 50, 250, 80, 50, 50, 250, 50, 50, 50, 250, 50, 50, 50, 40, 50, 10, 26 30, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 40, 20, 20, 10, 27 30, 20, 20, 50, 50, 50, 50, 50, 50, 50, 40, 20, 20, 20, 20, 20, 10, 28 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 10, 10, 10, 10, 10, 29 // ^ 30 ]; 31 32 __gshared static short[] TERRAIN_SCALE_DATA = [ 33 // V 34 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 35 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 36 20, 20, 20, 20, 120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 37 20, 20, 20, 20, 20, 20, 20, 20, 40, 60, 50, 20, 20, 30, 20, 20, 20, 38 20, 20, 120, 20, 20, 20, 20, 20, 20, 50, 20, 20, 20, 45, 20, 20, 20, 39 20, 20, 20, 20, 20, 20, 20, 20, 80, 20, 50, 20, 40, 50, 40, 20, 20, 40 20, 20, 20, 20, 20, 20, 90, 20, 80, 20, 80, 20, 20, 30, 20, 20, 20, 41 20, 20, 20, 20, 20, 90, 20, 80, 30, 20, 40, 20, 20, 20, 20, 20, 20, 42 20, 20, 20, 20, 20, 20, 90, 30, 20, 30, 50, 120, 20, 20, 20, 20, 20, // <== 43 20, 20, 20, 20, 20, 20, 50, 20, 30, 20, 20, 20, 20, 20, 20, 20, 20, 44 20, 20, 20, 20, 20, 20, 40, 70, 40, 90, 20, 40, 20, 20, 20, 20, 20, 45 20, 20, 20, 20, 20, 20, 80, 20, 80, 20, 50, 70, 50, 20, 20, 20, 20, 46 20, 20, 20, 20, 20, 20, 80, 20, 20, 20, 20, 60, 20, 20, 20, 20, 20, 47 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 48 20, 20, 20, 120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 120, 20, 20, 20, 49 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 51 // ^ 52 ]; 53 54 void initWorldTerrain(World world, int terrSizeBits = 10, int x0 = 0, int z0 = 0) { 55 import dminer.core.terrain; 56 int terrSize = 1 << terrSizeBits; 57 TerrainGen scaleterr = TerrainGen(terrSizeBits, terrSizeBits); // 512x512 58 scaleterr.generate(4321, TERRAIN_SCALE_DATA, terrSizeBits - 4); // init grid is 16x16 (1 << (9-7)) 59 //scaleterr.filter(1); 60 //scaleterr.filter(2); 61 scaleterr.limit(0, 90); 62 TerrainGen terr = TerrainGen(terrSizeBits, terrSizeBits); // 512x512 63 terr.generateWithScale(123456, TERRAIN_INIT_DATA, terrSizeBits - 4, scaleterr); // init grid is 16x16 (1 << (9-7)) 64 //terr.filter(1); 65 terr.limit(5, CHUNK_DY * 3 / 4); 66 terr.filter(1); 67 for (int x = 0; x < terrSize; x++) { 68 for (int z = 0; z < terrSize; z++) { 69 int cellx = x0 + x - terrSize / 2; 70 int cellz = z0 + z - terrSize / 2; 71 int h = terr.get(x, z); 72 int dh = terr.getHeightDiff(x, z); 73 74 75 cell_t cell = BlockId.bedrock; 76 //cell_t cell = BlockId.grass; 77 //cell_t cell = BlockId.face_test; 78 //if (h < CHUNK_DY / 10) 79 // cell = 100; 80 //else if (h < CHUNK_DY / 5) 81 // cell = 101; 82 //else if (h < CHUNK_DY / 4) 83 // cell = 102; 84 //else if (h < CHUNK_DY / 3) 85 // cell = 103; 86 //else if (h < CHUNK_DY / 2) 87 // cell = 104; 88 //else 89 // cell = 105; 90 91 cell_t topcell = BlockId.bedrock; 92 if (dh <= 1) 93 topcell = BlockId.grass; 94 95 for (int y = 0; y < h; y++) { 96 world.setCell(cellx, y, cellz, cell); 97 } 98 world.setCell(cellx, h, cellz, topcell); 99 } 100 } 101 } 102 103 104 void makeCastleWall(World world, Vector3d start, Vector3d direction, int height, int length, int width, cell_t material) { 105 Vector3d normal = direction.turnLeft; 106 for (int x = 0; x < length; x++) { 107 Vector3d x0 = start + direction * x; 108 for (int y = 0; y < height; y++) { 109 Vector3d y0 = x0; 110 y0.y += y; 111 for (int z = -width / 2; z <= width / 2; z++) { 112 Vector3d z0 = y0 + normal * z; 113 bool side = (z == -width/2 || z == width/2); 114 cell_t cell = material; 115 if (y >= height - 2) { 116 if (!side) 117 cell = BlockId.air; 118 else if ((x & 1) && (y >= height - 1)) { 119 cell = BlockId.air; 120 } 121 } 122 if (cell != BlockId.air) 123 world.setCell(z0.x, z0.y, z0.z, cell); 124 } 125 } 126 } 127 } 128 129 void makeCastleWalls(World world, Vector3d start, int size, int height, int width, cell_t material) { 130 world.makeCastleWall(Vector3d(start.x - size - width/2, start.y, start.z - size), Vector3d(1, 0, 0), height, size * 2 + width, width, material); 131 world.makeCastleWall(Vector3d(start.x - size, start.y, start.z - size - width/2), Vector3d(0, 0, 1), height, size * 2 + width, width, material); 132 world.makeCastleWall(Vector3d(start.x + size, start.y, start.z - size - width/2), Vector3d(0, 0, 1), height, size * 2 + width, width, material); 133 world.makeCastleWall(Vector3d(start.x - size - width/2, start.y, start.z + size), Vector3d(1, 0, 0), height, size * 2 + width, width, material); 134 } 135 136 void prepareCastleBase(World world, Vector3d start, int size) { 137 // basement - bedrock 138 world.setCellRange(Vector3d(start.x - size - 3, start.y - 10, start.z - size - 3), Vector3d(size*2 + 6, 10, size*2 + 6), BlockId.bedrock); 139 world.setCellRange(Vector3d(start.x - size - 4, start.y - 11, start.z - size - 4), Vector3d(size*2 + 8, 10, size*2 + 8), BlockId.bedrock); 140 // empty 141 world.setCellRange(Vector3d(start.x - size - 5, start.y, start.z - size - 5), Vector3d(size*2 + 10, 10, size*2 + 10), BlockId.air); 142 world.setCellRange(Vector3d(start.x - size - 6, start.y + 1, start.z - size - 6), Vector3d(size*2 + 12, 10, size*2 + 12), BlockId.air); 143 world.setCellRange(Vector3d(start.x - size - 7, start.y + 2, start.z - size - 7), Vector3d(size*2 + 14, 10, size*2 + 14), BlockId.air); 144 // floor 145 world.setCellRange(Vector3d(start.x - size, start.y - 10, start.z - size), Vector3d(size*2, 10, size*2), BlockId.red_sand);//cobblestone 146 } 147 148 void makeCastle(World world, Vector3d start, int size, int height) { 149 world.prepareCastleBase(start, size); 150 // main walls 151 world.makeCastleWalls(start, size, height, 4, BlockId.brick); 152 // gates 153 world.setCellRange(Vector3d(start.x - 3, start.y - 1, start.z - size - 7), Vector3d(7, 1, 10), BlockId.cobblestone); 154 world.setCellRange(Vector3d(start.x - 3, start.y - 2, start.z - size - 8), Vector3d(7, 1, 10), BlockId.cobblestone); 155 world.setCellRange(Vector3d(start.x - 3, start.y - 3, start.z - size - 9), Vector3d(7, 1, 10), BlockId.cobblestone); 156 world.setCellRange(Vector3d(start.x - 3, start.y, start.z - size - 4), Vector3d(7, height * 7 / 10, 7), BlockId.air); 157 world.setCellRange(Vector3d(start.x - 4, start.y, start.z - size), Vector3d(9, height * 7 / 10 + 1, 1), BlockId.air); 158 // corner towers 159 world.makeCastleWalls(start + Vector3d(-size + 1, -5, -size + 1), 5, height + 2 + 5, 3, BlockId.gray_brick); 160 world.makeCastleWalls(start + Vector3d(size - 1, -5, -size + 1), 5, height + 2 + 5, 3, BlockId.gray_brick); 161 world.makeCastleWalls(start + Vector3d(-size + 1, -5, size - 1), 5, height + 2 + 5, 3, BlockId.gray_brick); 162 world.makeCastleWalls(start + Vector3d(size - 1, -5, size - 1), 5, height + 2 + 5, 3, BlockId.gray_brick); 163 // dungeon 164 world.makeCastleWalls(start, size / 3, height * 15 / 10, 2, BlockId.gray_brick); 165 world.setCellRange(Vector3d(start.x - 2, start.y, start.z - size - 4), Vector3d(5, height * 6 / 10, size), BlockId.air); 166 }