the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 803 lines 30 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.entity.item.h" 3#include "net.minecraft.world.level.levelgen.structure.h" 4#include "net.minecraft.world.level.h" 5#include "net.minecraft.world.level.tile.h" 6#include "net.minecraft.world.level.tile.entity.h" 7#include "net.minecraft.world.item.h" 8#include "JavaMath.h" 9#include "WeighedTreasure.h" 10#include "MineShaftPieces.h" 11 12WeighedTreasureArray MineShaftPieces::smallTreasureItems;; 13 14void MineShaftPieces::staticCtor() 15{ 16 smallTreasureItems = WeighedTreasureArray(13); 17 smallTreasureItems[0] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); 18 smallTreasureItems[1] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5); 19 smallTreasureItems[2] = new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5); 20 smallTreasureItems[3] = new WeighedTreasure(Item::dye_powder_Id, DyePowderItem::BLUE, 4, 9, 5); 21 smallTreasureItems[4] = new WeighedTreasure(Item::diamond_Id, 0, 1, 2, 3); 22 smallTreasureItems[5] = new WeighedTreasure(Item::coal_Id, CoalItem::STONE_COAL, 3, 8, 10); 23 smallTreasureItems[6] = new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15); 24 smallTreasureItems[7] = new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 1); 25 smallTreasureItems[8] = new WeighedTreasure(Tile::rail_Id, 0, 4, 8, 1); 26 smallTreasureItems[9] = new WeighedTreasure(Item::seeds_melon_Id, 0, 2, 4, 10); 27 smallTreasureItems[10] = new WeighedTreasure(Item::seeds_pumpkin_Id, 0, 2, 4, 10); 28 // very rare for shafts ... 29 smallTreasureItems[11] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3); 30 smallTreasureItems[12] = new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1); 31} 32 33void MineShaftPieces::loadStatic() 34{ 35 StructureFeatureIO::setPieceId( eStructurePiece_MineShaftCorridor, MineShaftCorridor::Create, L"MSCorridor"); 36 StructureFeatureIO::setPieceId( eStructurePiece_MineShaftCrossing, MineShaftCrossing::Create, L"MSCrossing"); 37 StructureFeatureIO::setPieceId( eStructurePiece_MineShaftRoom, MineShaftRoom::Create, L"MSRoom"); 38 StructureFeatureIO::setPieceId( eStructurePiece_MineShaftStairs, MineShaftStairs::Create, L"MSStairs"); 39} 40 41StructurePiece *MineShaftPieces::createRandomShaftPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 42{ 43 int randomSelection = random->nextInt(100); 44 if (randomSelection >= 80) 45 { 46 BoundingBox *crossingBox = MineShaftCrossing::findCrossing(pieces, random, footX, footY, footZ, direction); 47 if (crossingBox != NULL) 48 { 49 return new MineShaftCrossing(genDepth, random, crossingBox, direction); 50 } 51 } 52 else if (randomSelection >= 70) 53 { 54 BoundingBox *stairsBox = MineShaftStairs::findStairs(pieces, random, footX, footY, footZ, direction); 55 if (stairsBox != NULL) 56 { 57 return new MineShaftPieces::MineShaftStairs(genDepth, random, stairsBox, direction); 58 } 59 } 60 else 61 { 62 BoundingBox *corridorBox = MineShaftCorridor::findCorridorSize(pieces, random, footX, footY, footZ, direction); 63 if (corridorBox != NULL) 64 { 65 return new MineShaftCorridor(genDepth, random, corridorBox, direction); 66 } 67 } 68 69 return NULL; 70} 71 72StructurePiece *MineShaftPieces::generateAndAddPiece(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth) 73{ 74 if (depth > MAX_DEPTH) 75 { 76 return NULL; 77 } 78 if (abs(footX - startPiece->getBoundingBox()->x0) > 5 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 5 * 16) 79 { 80 return NULL; 81 } 82 83 StructurePiece *newPiece = createRandomShaftPiece(pieces, random, footX, footY, footZ, direction, depth + 1); 84 if (newPiece != NULL) 85 { 86 MemSect(50); 87 pieces->push_back(newPiece); 88 MemSect(0); 89 newPiece->addChildren(startPiece, pieces, random); 90 } 91 return newPiece; 92} 93 94MineShaftPieces::MineShaftRoom::MineShaftRoom() 95{ 96 // for reflection 97} 98 99MineShaftPieces::MineShaftRoom::MineShaftRoom(int genDepth, Random *random, int west, int north) : StructurePiece(genDepth) 100{ 101 boundingBox = new BoundingBox(west, 50, north, west + 7 + random->nextInt(6), 54 + random->nextInt(6), north + 7 + random->nextInt(6)); 102} 103 104MineShaftPieces::MineShaftRoom::~MineShaftRoom() 105{ 106 for(AUTO_VAR(it, childEntranceBoxes.begin()); it != childEntranceBoxes.end(); ++it) 107 { 108 delete (*it); 109 } 110} 111 112void MineShaftPieces::MineShaftRoom::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 113{ 114 115 int depth = getGenDepth(); 116 117 int pos; 118 119 int heightSpace = boundingBox->getYSpan() - DEFAULT_SHAFT_HEIGHT - 1; 120 if (heightSpace <= 0) 121 { 122 heightSpace = 1; 123 } 124 125 // northern exits 126 pos = 0; 127 while (pos < boundingBox->getXSpan()) 128 { 129 pos += random->nextInt(boundingBox->getXSpan()); 130 if ((pos + DEFAULT_SHAFT_WIDTH) > boundingBox->getXSpan()) 131 { 132 break; 133 } 134 StructurePiece *child = generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + pos, boundingBox->y0 + random->nextInt(heightSpace) + 1, boundingBox->z0 - 1, Direction::NORTH, depth); 135 if (child != NULL) 136 { 137 BoundingBox *childBox = child->getBoundingBox(); 138 childEntranceBoxes.push_back(new BoundingBox(childBox->x0, childBox->y0, boundingBox->z0, childBox->x1, childBox->y1, boundingBox->z0 + 1)); 139 } 140 pos += DEFAULT_SHAFT_WIDTH + 1; 141 } 142 // southern exits 143 pos = 0; 144 while (pos < boundingBox->getXSpan()) 145 { 146 pos += random->nextInt(boundingBox->getXSpan()); 147 if ((pos + DEFAULT_SHAFT_WIDTH) > boundingBox->getXSpan()) 148 { 149 break; 150 } 151 StructurePiece *child = generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + pos, boundingBox->y0 + random->nextInt(heightSpace) + 1, boundingBox->z1 + 1, Direction::SOUTH, depth); 152 if (child != NULL) 153 { 154 BoundingBox *childBox = child->getBoundingBox(); 155 childEntranceBoxes.push_back(new BoundingBox(childBox->x0, childBox->y0, boundingBox->z1 - 1, childBox->x1, childBox->y1, boundingBox->z1)); 156 } 157 pos += DEFAULT_SHAFT_WIDTH + 1; 158 } 159 // western exits 160 pos = 0; 161 while (pos < boundingBox->getZSpan()) 162 { 163 pos += random->nextInt(boundingBox->getZSpan()); 164 if ((pos + DEFAULT_SHAFT_WIDTH) > boundingBox->getZSpan()) 165 { 166 break; 167 } 168 StructurePiece *child = generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + random->nextInt(heightSpace) + 1, boundingBox->z0 + pos, Direction::WEST, depth); 169 if (child != NULL) 170 { 171 BoundingBox *childBox = child->getBoundingBox(); 172 childEntranceBoxes.push_back(new BoundingBox(boundingBox->x0, childBox->y0, childBox->z0, boundingBox->x0 + 1, childBox->y1, childBox->z1)); 173 } 174 pos += DEFAULT_SHAFT_WIDTH + 1; 175 } 176 // eastern exits 177 pos = 0; 178 while (pos < boundingBox->getZSpan()) 179 { 180 pos += random->nextInt(boundingBox->getZSpan()); 181 if ((pos + DEFAULT_SHAFT_WIDTH) > boundingBox->getZSpan()) 182 { 183 break; 184 } 185 StructurePiece *child = generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + random->nextInt(heightSpace) + 1, boundingBox->z0 + pos, Direction::EAST, depth); 186 if (child != NULL) 187 { 188 BoundingBox *childBox = child->getBoundingBox(); 189 childEntranceBoxes.push_back(new BoundingBox(boundingBox->x1 - 1, childBox->y0, childBox->z0, boundingBox->x1, childBox->y1, childBox->z1)); 190 } 191 pos += DEFAULT_SHAFT_WIDTH + 1; 192 } 193} 194 195bool MineShaftPieces::MineShaftRoom::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 196{ 197 if (edgesLiquid(level, chunkBB)) 198 { 199 return false; 200 } 201 202 // floor 203 generateBox(level, chunkBB, boundingBox->x0, boundingBox->y0, boundingBox->z0, boundingBox->x1, boundingBox->y0, boundingBox->z1, Tile::dirt_Id, 0, true); 204 205 // room air 206 generateBox(level, chunkBB, boundingBox->x0, boundingBox->y0 + 1, boundingBox->z0, boundingBox->x1, min(boundingBox->y0 + 3, boundingBox->y1), boundingBox->z1, 0, 0, false); 207 for(AUTO_VAR(it, childEntranceBoxes.begin()); it != childEntranceBoxes.end(); ++it) 208 { 209 BoundingBox *entranceBox = *it; 210 generateBox(level, chunkBB, entranceBox->x0, entranceBox->y1 - (DEFAULT_SHAFT_HEIGHT - 1), entranceBox->z0, entranceBox->x1, entranceBox->y1, entranceBox->z1, 0, 0, false); 211 } 212 generateUpperHalfSphere(level, chunkBB, boundingBox->x0, boundingBox->y0 + 4, boundingBox->z0, boundingBox->x1, boundingBox->y1, boundingBox->z1, 0, false); 213 214 return true; 215} 216 217void MineShaftPieces::MineShaftRoom::addAdditonalSaveData(CompoundTag *tag) 218{ 219 ListTag<IntArrayTag> *entrances = new ListTag<IntArrayTag>(L"Entrances"); 220 for (AUTO_VAR(it,childEntranceBoxes.begin()); it != childEntranceBoxes.end(); ++it) 221 { 222 BoundingBox *bb =*it; 223 entrances->add(bb->createTag(L"")); 224 } 225 tag->put(L"Entrances", entrances); 226} 227 228void MineShaftPieces::MineShaftRoom::readAdditonalSaveData(CompoundTag *tag) 229{ 230 ListTag<IntArrayTag> *entrances = (ListTag<IntArrayTag> *) tag->getList(L"Entrances"); 231 for (int i = 0; i < entrances->size(); i++) 232 { 233 childEntranceBoxes.push_back(new BoundingBox(entrances->get(i)->data)); 234 } 235} 236 237MineShaftPieces::MineShaftCorridor::MineShaftCorridor() 238{ 239 // for reflection 240} 241 242void MineShaftPieces::MineShaftCorridor::addAdditonalSaveData(CompoundTag *tag) 243{ 244 tag->putBoolean(L"hr", hasRails); 245 tag->putBoolean(L"sc", spiderCorridor); 246 tag->putBoolean(L"hps", hasPlacedSpider); 247 tag->putInt(L"Num", numSections); 248} 249 250void MineShaftPieces::MineShaftCorridor::readAdditonalSaveData(CompoundTag *tag) 251{ 252 hasRails = tag->getBoolean(L"hr"); 253 spiderCorridor = tag->getBoolean(L"sc"); 254 hasPlacedSpider = tag->getBoolean(L"hps"); 255 numSections = tag->getInt(L"Num"); 256} 257 258MineShaftPieces::MineShaftCorridor::MineShaftCorridor(int genDepth, Random *random, BoundingBox *corridorBox, int direction) 259 : StructurePiece(genDepth) 260{ 261 orientation = direction; 262 boundingBox = corridorBox; 263 hasRails = random->nextInt(3) == 0; 264 hasPlacedSpider=false; 265 spiderCorridor = !hasRails && random->nextInt(23) == 0; 266 //debug 267 //spiderCorridor = !hasRails ;//&& random->nextInt(23) == 0; 268 269 if (orientation == Direction::NORTH || orientation == Direction::SOUTH) 270 { 271 numSections = corridorBox->getZSpan() / DEFAULT_SHAFT_LENGTH; 272 } 273 else 274 { 275 numSections = corridorBox->getXSpan() / DEFAULT_SHAFT_LENGTH; 276 } 277} 278 279BoundingBox *MineShaftPieces::MineShaftCorridor::findCorridorSize(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction) 280{ 281 282 BoundingBox *box = new BoundingBox(footX, footY, footZ, footX, footY + (DEFAULT_SHAFT_HEIGHT - 1), footZ); 283 284 int corridorLength = random->nextInt(3) + 2; 285 while (corridorLength > 0) 286 { 287 int blockLength = corridorLength * DEFAULT_SHAFT_LENGTH; 288 289 switch (direction) 290 { 291 case Direction::NORTH: 292 box->x1 = footX + (DEFAULT_SHAFT_WIDTH - 1); 293 box->z0 = footZ - (blockLength - 1); 294 break; 295 case Direction::SOUTH: 296 box->x1 = footX + (DEFAULT_SHAFT_WIDTH - 1); 297 box->z1 = footZ + (blockLength - 1); 298 break; 299 case Direction::WEST: 300 box->x0 = footX - (blockLength - 1); 301 box->z1 = footZ + (DEFAULT_SHAFT_WIDTH - 1); 302 break; 303 case Direction::EAST: 304 box->x1 = footX + (blockLength - 1); 305 box->z1 = footZ + (DEFAULT_SHAFT_WIDTH - 1); 306 break; 307 } 308 309 if (StructurePiece::findCollisionPiece(pieces, box) != NULL) 310 { 311 corridorLength--; 312 } 313 else 314 { 315 break; 316 } 317 } 318 319 if (corridorLength > 0) 320 { 321 return box; 322 } 323 delete box; 324 // unable to place corridor here 325 return NULL; 326} 327 328void MineShaftPieces::MineShaftCorridor::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 329{ 330 int depth = getGenDepth(); 331 int endSelection = random->nextInt(4); 332 switch (orientation) 333 { 334 case Direction::NORTH: 335 if (endSelection <= 1) 336 { 337 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0 - 1, orientation, depth); 338 } 339 else if (endSelection == 2) 340 { 341 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0, Direction::WEST, depth); 342 } 343 else 344 { 345 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0, Direction::EAST, depth); 346 } 347 break; 348 case Direction::SOUTH: 349 if (endSelection <= 1) 350 { 351 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z1 + 1, orientation, depth); 352 } 353 else if (endSelection == 2) 354 { 355 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z1 - DEFAULT_SHAFT_WIDTH, Direction::WEST, depth); 356 } 357 else 358 { 359 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z1 - DEFAULT_SHAFT_WIDTH, Direction::EAST, depth); 360 } 361 break; 362 case Direction::WEST: 363 if (endSelection <= 1) 364 { 365 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0, orientation, depth); 366 } 367 else if (endSelection == 2) 368 { 369 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0 - 1, Direction::NORTH, depth); 370 } 371 else 372 { 373 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z1 + 1, Direction::SOUTH, depth); 374 } 375 break; 376 case Direction::EAST: 377 if (endSelection <= 1) 378 { 379 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0, orientation, depth); 380 } 381 else if (endSelection == 2) 382 { 383 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 - DEFAULT_SHAFT_WIDTH, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z0 - 1, Direction::NORTH, depth); 384 } 385 else 386 { 387 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 - DEFAULT_SHAFT_WIDTH, boundingBox->y0 - 1 + random->nextInt(3), boundingBox->z1 + 1, Direction::SOUTH, depth); 388 } 389 break; 390 } 391 392 // generate cross sections using higher depth 393 if (depth < MAX_DEPTH) 394 { 395 if (orientation == Direction::NORTH || orientation == Direction::SOUTH) 396 { 397 for (int z = boundingBox->z0 + 3; (z + DEFAULT_SHAFT_WIDTH) <= boundingBox->z1; z += DEFAULT_SHAFT_LENGTH) 398 { 399 int selection = random->nextInt(5); 400 if (selection == 0) 401 { 402 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0, z, Direction::WEST, depth + 1); 403 } 404 else if (selection == 1) 405 { 406 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0, z, Direction::EAST, depth + 1); 407 } 408 } 409 } 410 else 411 { 412 for (int x = boundingBox->x0 + 3; (x + DEFAULT_SHAFT_WIDTH) <= boundingBox->x1; x += DEFAULT_SHAFT_LENGTH) 413 { 414 int selection = random->nextInt(5); 415 if (selection == 0) 416 { 417 generateAndAddPiece(startPiece, pieces, random, x, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, depth + 1); 418 } 419 else if (selection == 1) 420 { 421 generateAndAddPiece(startPiece, pieces, random, x, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, depth + 1); 422 } 423 } 424 } 425 } 426} 427 428bool MineShaftPieces::MineShaftCorridor::createChest(Level *level, BoundingBox *chunkBB, Random *random, int x, int y, int z, WeighedTreasureArray treasure, int numRolls) 429{ 430 int worldX = getWorldX(x, z); 431 int worldY = getWorldY(y); 432 int worldZ = getWorldZ(x, z); 433 434 if (chunkBB->isInside(worldX, worldY, worldZ)) 435 { 436 if (level->getTile(worldX, worldY, worldZ) == 0) 437 { 438 level->setTileAndData(worldX, worldY, worldZ, Tile::rail_Id, getOrientationData(Tile::rail_Id, random->nextBoolean() ? RailTile::DIR_FLAT_X : RailTile::DIR_FLAT_Z), Tile::UPDATE_CLIENTS); 439 shared_ptr<MinecartChest> chest = shared_ptr<MinecartChest>( new MinecartChest(level, worldX + 0.5f, worldY + 0.5f, worldZ + 0.5f) ); 440 WeighedTreasure::addChestItems(random, treasure, chest, numRolls); 441 level->addEntity(chest); 442 return true; 443 } 444 } 445 446 return false; 447} 448 449bool MineShaftPieces::MineShaftCorridor::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 450{ 451 if (edgesLiquid(level, chunkBB)) 452 { 453 return false; 454 } 455 456 const int x0 = 0; 457 const int x1 = DEFAULT_SHAFT_WIDTH - 1; 458 const int y0 = 0; 459 const int y1 = DEFAULT_SHAFT_HEIGHT - 1; 460 const int length = (numSections * DEFAULT_SHAFT_LENGTH) - 1; 461 462 // corridor air 463 generateBox(level, chunkBB, x0, 0, y0, x1, y1 - 1, length, 0, 0, false); 464 generateMaybeBox(level, chunkBB, random, .8f, x0, y1, y0, x1, y1, length, 0, 0, false); 465 466 if (spiderCorridor) 467 { 468 generateMaybeBox(level, chunkBB, random, .6f, x0, 0, y0, x1, y1 - 1, length, Tile::web_Id, 0, false); 469 } 470 471 // place a support in every section 472 for (int section = 0; section < numSections; section++) 473 { 474 475 int z = 2 + section * DEFAULT_SHAFT_LENGTH; 476 477 // 4J-PB - Bringing forward the changes in 1.2.3 478 generateBox(level, chunkBB, x0, y0, z, x0, y1 - 1, z, Tile::fence_Id, 0, false); 479 generateBox(level, chunkBB, x1, y0, z, x1, y1 - 1, z, Tile::fence_Id, 0, false); 480 if (random->nextInt(4) == 0) 481 { 482 generateBox(level, chunkBB, x0, y1, z, x0, y1, z, Tile::wood_Id, 0, false); 483 generateBox(level, chunkBB, x1, y1, z, x1, y1, z, Tile::wood_Id, 0, false); 484 } 485 else 486 { 487 generateBox(level, chunkBB, x0, y1, z, x1, y1, z, Tile::wood_Id, 0, false); 488 } 489 maybeGenerateBlock(level, chunkBB, random, .1f, x0, y1, z - 1, Tile::web_Id, 0); 490 maybeGenerateBlock(level, chunkBB, random, .1f, x1, y1, z - 1, Tile::web_Id, 0); 491 maybeGenerateBlock(level, chunkBB, random, .1f, x0, y1, z + 1, Tile::web_Id, 0); 492 maybeGenerateBlock(level, chunkBB, random, .1f, x1, y1, z + 1, Tile::web_Id, 0); 493 maybeGenerateBlock(level, chunkBB, random, .05f, x0, y1, z - 2, Tile::web_Id, 0); 494 maybeGenerateBlock(level, chunkBB, random, .05f, x1, y1, z - 2, Tile::web_Id, 0); 495 maybeGenerateBlock(level, chunkBB, random, .05f, x0, y1, z + 2, Tile::web_Id, 0); 496 maybeGenerateBlock(level, chunkBB, random, .05f, x1, y1, z + 2, Tile::web_Id, 0); 497 498 maybeGenerateBlock(level, chunkBB, random, .05f, x0 + 1, y1, z - 1, Tile::torch_Id, 0); 499 maybeGenerateBlock(level, chunkBB, random, .05f, x0 + 1, y1, z + 1, Tile::torch_Id, 0); 500 501 if (random->nextInt(100) == 0) 502 { 503 createChest(level, chunkBB, random, x1, y0, z - 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchantedBook->createForRandomTreasure(random)), 3 + random->nextInt(4)); 504 } 505 if (random->nextInt(100) == 0) 506 { 507 createChest(level, chunkBB, random, x0, y0, z + 1, WeighedTreasure::addToTreasure(smallTreasureItems, Item::enchantedBook->createForRandomTreasure(random)), 3 + random->nextInt(4)); 508 } 509 510 if (spiderCorridor && !hasPlacedSpider) 511 { 512 int y = getWorldY(y0), newZ = z - 1 + random->nextInt(3); 513 int x = getWorldX(x0 + 1, newZ); 514 newZ = getWorldZ(x0 + 1, newZ); 515 if (chunkBB->isInside(x, y, newZ)) 516 { 517 hasPlacedSpider = true; 518 level->setTileAndData(x, y, newZ, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); 519 shared_ptr<MobSpawnerTileEntity> entity = dynamic_pointer_cast<MobSpawnerTileEntity>( level->getTileEntity(x, y, newZ) ); 520 if (entity != NULL) entity->getSpawner()->setEntityId(L"CaveSpider"); 521 } 522 } 523 } 524 525 // prevent air floating 526 for (int x = x0; x <= x1; x++) 527 { 528 for (int z = 0; z <= length; z++) 529 { 530 int block = getBlock(level, x, -1, z, chunkBB); 531 if (block == 0) 532 { 533 placeBlock(level, Tile::wood_Id, 0, x, -1, z, chunkBB); 534 } 535 } 536 } 537 538 if (hasRails) 539 { 540 for (int z = 0; z <= length; z++) 541 { 542 int floor = getBlock(level, x0 + 1, y0 - 1, z, chunkBB); 543 if (floor > 0 && Tile::solid[floor]) 544 { 545 maybeGenerateBlock(level, chunkBB, random, .7f, x0 + 1, y0, z, Tile::rail_Id, getOrientationData(Tile::rail_Id, BaseRailTile::DIR_FLAT_Z)); 546 } 547 } 548 } 549 550 return true; 551} 552 553MineShaftPieces::MineShaftCrossing::MineShaftCrossing() 554{ 555 // for reflection 556} 557 558void MineShaftPieces::MineShaftCrossing::addAdditonalSaveData(CompoundTag *tag) 559{ 560 tag->putBoolean(L"tf", isTwoFloored); 561 tag->putInt(L"D", direction); 562} 563 564void MineShaftPieces::MineShaftCrossing::readAdditonalSaveData(CompoundTag *tag) 565{ 566 isTwoFloored = tag->getBoolean(L"tf"); 567 direction = tag->getInt(L"D"); 568} 569 570MineShaftPieces::MineShaftCrossing::MineShaftCrossing(int genDepth, Random *random, BoundingBox *crossingBox, int direction) 571 : StructurePiece(genDepth), direction(direction), isTwoFloored( crossingBox->getYSpan() > DEFAULT_SHAFT_HEIGHT ) 572{ 573 boundingBox = crossingBox; 574} 575 576BoundingBox *MineShaftPieces::MineShaftCrossing::findCrossing(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction) 577{ 578 579 BoundingBox *box = new BoundingBox(footX, footY, footZ, footX, footY + (DEFAULT_SHAFT_HEIGHT - 1), footZ); 580 581 if (random->nextInt(4) == 0) 582 { 583 box->y1 += DEFAULT_SHAFT_HEIGHT + 1; // two-floored 584 } 585 586 switch (direction) 587 { 588 case Direction::NORTH: 589 box->x0 = footX - 1; 590 box->x1 = footX + DEFAULT_SHAFT_WIDTH; 591 box->z0 = footZ - (DEFAULT_SHAFT_WIDTH + 1); 592 break; 593 case Direction::SOUTH: 594 box->x0 = footX - 1; 595 box->x1 = footX + DEFAULT_SHAFT_WIDTH; 596 box->z1 = footZ + (DEFAULT_SHAFT_WIDTH + 1); 597 break; 598 case Direction::WEST: 599 box->x0 = footX - (DEFAULT_SHAFT_WIDTH + 1); 600 box->z0 = footZ - 1; 601 box->z1 = footZ + DEFAULT_SHAFT_WIDTH; 602 break; 603 case Direction::EAST: 604 box->x1 = footX + (DEFAULT_SHAFT_WIDTH + 1); 605 box->z0 = footZ - 1; 606 box->z1 = footZ + DEFAULT_SHAFT_WIDTH; 607 break; 608 } 609 610 if (StructurePiece::findCollisionPiece(pieces, box) != NULL) 611 { 612 delete box; 613 return NULL; 614 } 615 616 return box; 617} 618 619void MineShaftPieces::MineShaftCrossing::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 620{ 621 622 int depth = getGenDepth(); 623 // crossings are coming from a direction and will generate children 624 // in the 625 // remaining three directions 626 switch (direction) 627 { 628 case Direction::NORTH: 629 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, depth); 630 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z0 + 1, Direction::WEST, depth); 631 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z0 + 1, Direction::EAST, depth); 632 break; 633 case Direction::SOUTH: 634 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, depth); 635 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z0 + 1, Direction::WEST, depth); 636 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z0 + 1, Direction::EAST, depth); 637 break; 638 case Direction::WEST: 639 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, depth); 640 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, depth); 641 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z0 + 1, Direction::WEST, depth); 642 break; 643 case Direction::EAST: 644 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, depth); 645 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, depth); 646 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z0 + 1, Direction::EAST, depth); 647 break; 648 } 649 650 if (isTwoFloored) 651 { 652 if (random->nextBoolean()) generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT + 1, boundingBox->z0 - 1, Direction::NORTH, depth); 653 if (random->nextBoolean()) generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT + 1, boundingBox->z0 + 1, Direction::WEST, depth); 654 if (random->nextBoolean()) generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT + 1, boundingBox->z0 + 1, Direction::EAST, depth); 655 if (random->nextBoolean()) generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT + 1, boundingBox->z1 + 1, Direction::SOUTH, depth); 656 } 657} 658 659bool MineShaftPieces::MineShaftCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 660{ 661 if (edgesLiquid(level, chunkBB)) 662 { 663 return false; 664 } 665 666 // corridor air 667 if (isTwoFloored) 668 { 669 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0, boundingBox->x1 - 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT - 1, boundingBox->z1, 0, 0, false); 670 generateBox(level, chunkBB, boundingBox->x0, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT - 1, boundingBox->z1 - 1, 0, 0, false); 671 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y1 - (DEFAULT_SHAFT_HEIGHT - 1), boundingBox->z0, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z1, 0, 0, false); 672 generateBox(level, chunkBB, boundingBox->x0, boundingBox->y1 - (DEFAULT_SHAFT_HEIGHT - 1), boundingBox->z0 + 1, boundingBox->x1, boundingBox->y1, boundingBox->z1 - 1, 0, 0, false); 673 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT, boundingBox->z0 + 1, boundingBox->x1 - 1, boundingBox->y0 + DEFAULT_SHAFT_HEIGHT, boundingBox->z1 - 1, 0, 0, false); 674 } 675 else 676 { 677 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z1, 0, 0, false); 678 generateBox(level, chunkBB, boundingBox->x0, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x1, boundingBox->y1, boundingBox->z1 - 1, 0, 0, false); 679 } 680 681 // support pillars 682 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z0 + 1, Tile::wood_Id, 0, false); 683 generateBox(level, chunkBB, boundingBox->x0 + 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x0 + 1, boundingBox->y1, boundingBox->z1 - 1, Tile::wood_Id, 0, false); 684 generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z0 + 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z0 + 1, Tile::wood_Id, 0, false); 685 generateBox(level, chunkBB, boundingBox->x1 - 1, boundingBox->y0, boundingBox->z1 - 1, boundingBox->x1 - 1, boundingBox->y1, boundingBox->z1 - 1, Tile::wood_Id, 0, false); 686 687 // prevent air floating 688 // note: use world coordinates because the corridor hasn't defined 689 // orientation 690 for (int x = boundingBox->x0; x <= boundingBox->x1; x++) 691 { 692 for (int z = boundingBox->z0; z <= boundingBox->z1; z++) 693 { 694 int block = getBlock(level, x, boundingBox->y0 - 1, z, chunkBB); 695 if (block == 0) 696 { 697 placeBlock(level, Tile::wood_Id, 0, x, boundingBox->y0 - 1, z, chunkBB); 698 } 699 } 700 } 701 702 return true; 703} 704 705MineShaftPieces::MineShaftStairs::MineShaftStairs() 706{ 707 // for reflection 708} 709 710MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StructurePiece(genDepth) 711{ 712 this->orientation = direction; 713 boundingBox = stairsBox; 714} 715 716 717void MineShaftPieces::MineShaftStairs::addAdditonalSaveData(CompoundTag *tag) 718{ 719} 720 721void MineShaftPieces::MineShaftStairs::readAdditonalSaveData(CompoundTag *tag) 722{ 723} 724 725BoundingBox *MineShaftPieces::MineShaftStairs::findStairs(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction) 726{ 727 // stairs are two steps in, 5x5 steps down, two steps out 728 729 BoundingBox *box = new BoundingBox(footX, footY - 5, footZ, footX, footY + (DEFAULT_SHAFT_HEIGHT - 1), footZ); 730 731 switch (direction) 732 { 733 case Direction::NORTH: 734 box->x1 = footX + (DEFAULT_SHAFT_WIDTH - 1); 735 box->z0 = footZ - 8; 736 break; 737 case Direction::SOUTH: 738 box->x1 = footX + (DEFAULT_SHAFT_WIDTH - 1); 739 box->z1 = footZ + 8; 740 break; 741 case Direction::WEST: 742 box->x0 = footX - 8; 743 box->z1 = footZ + (DEFAULT_SHAFT_WIDTH - 1); 744 break; 745 case Direction::EAST: 746 box->x1 = footX + 8; 747 box->z1 = footZ + (DEFAULT_SHAFT_WIDTH - 1); 748 break; 749 } 750 751 if (StructurePiece::findCollisionPiece(pieces, box) != NULL) 752 { 753 delete box; 754 return NULL; 755 } 756 757 return box; 758} 759 760void MineShaftPieces::MineShaftStairs::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 761{ 762 int depth = getGenDepth(); 763 // crossings are coming from a direction and will generate children 764 // in the 765 // remaining three directions 766 switch (orientation) 767 { 768 case Direction::NORTH: 769 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, depth); 770 break; 771 case Direction::SOUTH: 772 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, depth); 773 break; 774 case Direction::WEST: 775 generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z0, Direction::WEST, depth); 776 break; 777 case Direction::EAST: 778 generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z0, Direction::EAST, depth); 779 break; 780 } 781 782} 783 784bool MineShaftPieces::MineShaftStairs::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 785{ 786 787 if (edgesLiquid(level, chunkBB)) 788 { 789 return false; 790 } 791 792 // upper floor 793 generateBox(level, chunkBB, 0, 5, 0, (DEFAULT_SHAFT_WIDTH - 1), 5 + (DEFAULT_SHAFT_HEIGHT - 1), 1, 0, 0, false); 794 // lower floor 795 generateBox(level, chunkBB, 0, 0, 7, (DEFAULT_SHAFT_WIDTH - 1), (DEFAULT_SHAFT_HEIGHT - 1), 8, 0, 0, false); 796 // stairs 797 for (int i = 0; i < 5; i++) 798 { 799 generateBox(level, chunkBB, 0, 5 - i - ((i < 4) ? 1 : 0), 2 + i, (DEFAULT_SHAFT_WIDTH - 1), 5 + (DEFAULT_SHAFT_HEIGHT - 1) - i, 2 + i, 0, 0, false); 800 } 801 802 return true; 803}