the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 1735 lines 67 kB view raw
1#include "stdafx.h" 2#include "StrongholdPieces.h" 3#include "net.minecraft.world.level.h" 4#include "net.minecraft.world.level.tile.h" 5#include "net.minecraft.world.level.tile.entity.h" 6#include "net.minecraft.world.level.storage.h" 7#include "net.minecraft.world.level.levelgen.h" 8#include "net.minecraft.world.level.levelgen.structure.h" 9#include "net.minecraft.world.item.h" 10#include "WeighedTreasure.h" 11#include "FileHeader.h" 12#include "Facing.h" 13 14int StrongholdPieces::totalWeight = 0; 15list<StrongholdPieces::PieceWeight *> StrongholdPieces::currentPieces; 16StrongholdPieces::EPieceClass StrongholdPieces::imposedPiece; 17const bool StrongholdPieces::CHECK_AIR = true; 18 19void StrongholdPieces::loadStatic() 20{ 21 StructureFeatureIO::setPieceId(eStructurePiece_ChestCorridor, ChestCorridor::Create, L"SHCC"); 22 StructureFeatureIO::setPieceId(eStructurePiece_FillerCorridor, FillerCorridor::Create, L"SHFC"); 23 StructureFeatureIO::setPieceId(eStructurePiece_FiveCrossing, FiveCrossing::Create, L"SH5C"); 24 StructureFeatureIO::setPieceId(eStructurePiece_LeftTurn, LeftTurn::Create, L"SHLT"); 25 StructureFeatureIO::setPieceId(eStructurePiece_Library, Library::Create, L"SHLi"); 26 StructureFeatureIO::setPieceId(eStructurePiece_PortalRoom, PortalRoom::Create, L"SHPR"); 27 StructureFeatureIO::setPieceId(eStructurePiece_PrisonHall, PrisonHall::Create, L"SHPH"); 28 StructureFeatureIO::setPieceId(eStructurePiece_RightTurn, RightTurn::Create, L"SHRT"); 29 StructureFeatureIO::setPieceId(eStructurePiece_StrongholdRoomCrossing, RoomCrossing::Create, L"SHRC"); 30 StructureFeatureIO::setPieceId(eStructurePiece_StairsDown, StairsDown::Create, L"SHSD"); 31 StructureFeatureIO::setPieceId(eStructurePiece_StrongholdStartPiece, StartPiece::Create, L"SHStart"); 32 StructureFeatureIO::setPieceId(eStructurePiece_Straight, Straight::Create, L"SHS"); 33 StructureFeatureIO::setPieceId(eStructurePiece_StraightStairsDown, StraightStairsDown::Create, L"SHSSD"); 34} 35 36StrongholdPieces::PieceWeight::PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount) : weight(weight) 37{ 38 this->placeCount = 0; // 4J added initialiser 39 this->pieceClass = pieceClass; 40 this->maxPlaceCount = maxPlaceCount; 41} 42 43bool StrongholdPieces::PieceWeight::doPlace(int depth) 44{ 45 return maxPlaceCount == 0 || placeCount < maxPlaceCount; 46} 47 48bool StrongholdPieces::PieceWeight::isValid() 49{ 50 return maxPlaceCount == 0 || placeCount < maxPlaceCount; 51} 52 53void StrongholdPieces::resetPieces() 54{ 55 for( AUTO_VAR(it, currentPieces.begin()); it != currentPieces.end(); it++ ) 56 { 57 delete (*it); 58 } 59 currentPieces.clear(); 60 61 currentPieces.push_back( new PieceWeight(EPieceClass_Straight, 40, 0) ); 62 currentPieces.push_back( new PieceWeight(EPieceClass_PrisonHall, 5, 5) ); 63 currentPieces.push_back( new PieceWeight(EPieceClass_LeftTurn, 20, 0) ); 64 currentPieces.push_back( new PieceWeight(EPieceClass_RightTurn, 20, 0) ); 65 currentPieces.push_back( new PieceWeight(EPieceClass_RoomCrossing, 10, 6) ); 66 currentPieces.push_back( new PieceWeight(EPieceClass_StraightStairsDown, 5, 5) ); 67 currentPieces.push_back( new PieceWeight(EPieceClass_StairsDown, 5, 5) ); 68 currentPieces.push_back( new PieceWeight(EPieceClass_FiveCrossing, 5, 4) ); 69 currentPieces.push_back( new PieceWeight(EPieceClass_ChestCorridor, 5, 4) ); 70 currentPieces.push_back( new PieceWeight_Library(EPieceClass_Library, 10, 2) ); 71 currentPieces.push_back( new PieceWeight_PortalRoom(EPieceClass_PortalRoom, 20, 1) ); 72 73 imposedPiece = EPieceClass_NULL; 74} 75 76bool StrongholdPieces::updatePieceWeight() 77{ 78 bool hasAnyPieces = false; 79 totalWeight = 0; 80 for( AUTO_VAR(it, currentPieces.begin()); it != currentPieces.end(); it++ ) 81 { 82 PieceWeight *piece = *it; 83 if (piece->maxPlaceCount > 0 && piece->placeCount < piece->maxPlaceCount) 84 { 85 hasAnyPieces = true; 86 } 87 totalWeight += piece->weight; 88 } 89 return hasAnyPieces; 90} 91 92StrongholdPieces::StrongholdPiece *StrongholdPieces::findAndCreatePieceFactory(EPieceClass pieceClass, list<StructurePiece*> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth) 93{ 94 StrongholdPiece *strongholdPiece = NULL; 95 96 if (pieceClass == EPieceClass_Straight) 97 { 98 strongholdPiece = Straight::createPiece(pieces, random, footX, footY, footZ, direction, depth); 99 } 100 else if (pieceClass == EPieceClass_PrisonHall) 101 { 102 strongholdPiece = PrisonHall::createPiece(pieces, random, footX, footY, footZ, direction, depth); 103 } 104 else if (pieceClass == EPieceClass_LeftTurn) 105 { 106 strongholdPiece = LeftTurn::createPiece(pieces, random, footX, footY, footZ, direction, depth); 107 } 108 else if (pieceClass == EPieceClass_RightTurn) 109 { 110 strongholdPiece = RightTurn::createPiece(pieces, random, footX, footY, footZ, direction, depth); 111 } 112 else if (pieceClass == EPieceClass_RoomCrossing) 113 { 114 strongholdPiece = RoomCrossing::createPiece(pieces, random, footX, footY, footZ, direction, depth); 115 } 116 else if (pieceClass == EPieceClass_StraightStairsDown) 117 { 118 strongholdPiece = StraightStairsDown::createPiece(pieces, random, footX, footY, footZ, direction, depth); 119 } 120 else if (pieceClass == EPieceClass_StairsDown) 121 { 122 strongholdPiece = StairsDown::createPiece(pieces, random, footX, footY, footZ, direction, depth); 123 } 124 else if (pieceClass == EPieceClass_FiveCrossing) 125 { 126 strongholdPiece = FiveCrossing::createPiece(pieces, random, footX, footY, footZ, direction, depth); 127 } 128 else if (pieceClass == EPieceClass_ChestCorridor) 129 { 130 strongholdPiece = ChestCorridor::createPiece(pieces, random, footX, footY, footZ, direction, depth); 131 } 132 else if (pieceClass == EPieceClass_Library) 133 { 134 strongholdPiece = Library::createPiece(pieces, random, footX, footY, footZ, direction, depth); 135 } 136 else if (pieceClass == EPieceClass_PortalRoom) 137 { 138 strongholdPiece = PortalRoom::createPiece(pieces, random, footX, footY, footZ, direction, depth); 139 } 140 141 142 return strongholdPiece; 143} 144 145StrongholdPieces::StrongholdPiece *StrongholdPieces::generatePieceFromSmallDoor(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth) 146{ 147 if (!updatePieceWeight()) 148 { 149 return NULL; 150 } 151 152 if (imposedPiece != EPieceClass_NULL) 153 { 154 StrongholdPiece *strongholdPiece = findAndCreatePieceFactory(imposedPiece, pieces, random, footX, footY, footZ, direction, depth); 155 imposedPiece = EPieceClass_NULL; 156 157 if (strongholdPiece != NULL) 158 { 159 return strongholdPiece; 160 } 161 } 162 163 int numAttempts = 0; 164 while (numAttempts < 5) 165 { 166 numAttempts++; 167 168 int weightSelection = random->nextInt(totalWeight); 169 for( AUTO_VAR(it, currentPieces.begin()); it != currentPieces.end(); it++ ) 170 { 171 PieceWeight *piece = *it; 172 weightSelection -= piece->weight; 173 if (weightSelection < 0) 174 { 175 if (!piece->doPlace(depth) || piece == startPiece->previousPiece) 176 { 177 break; 178 } 179 180 StrongholdPiece *strongholdPiece = findAndCreatePieceFactory(piece->pieceClass, pieces, random, footX, footY, footZ, direction, depth); 181 if (strongholdPiece != NULL) 182 { 183 piece->placeCount++; 184 startPiece->previousPiece = piece; 185 186 if (!piece->isValid()) 187 { 188 currentPieces.remove(piece); 189 } 190 return strongholdPiece; 191 } 192 } 193 } 194 } 195 { 196 BoundingBox *box = FillerCorridor::findPieceBox(pieces, random, footX, footY, footZ, direction); 197 if (box != NULL && box->y0 > 1) 198 { 199 return new FillerCorridor(depth, random, box, direction); 200 } 201 if(box != NULL) delete box; 202 } 203 204 return NULL; 205} 206 207StructurePiece *StrongholdPieces::generateAndAddPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth) 208{ 209 if (depth > MAX_DEPTH) 210 { 211 return NULL; 212 } 213 if (abs(footX - startPiece->getBoundingBox()->x0) > 3 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 3 * 16) 214 { 215 // Force attempt at spawning a portal room 216 if(startPiece->m_level->getOriginalSaveVersion() >= SAVE_FILE_VERSION_MOVED_STRONGHOLD && !startPiece->m_level->getLevelData()->getHasStrongholdEndPortal()) 217 { 218 for( AUTO_VAR(it, currentPieces.begin()); it != currentPieces.end(); it++ ) 219 { 220 PieceWeight *piece = *it; 221 222 if(piece->pieceClass != EPieceClass_PortalRoom) continue; 223 224#ifndef _CONTENT_PACKAGE 225 printf("Portal room forcing attempt\n"); 226#endif 227 StrongholdPiece *strongholdPiece = PortalRoom::createPiece(pieces, random, footX, footY, footZ, direction, depth); 228 if (strongholdPiece != NULL) 229 { 230 piece->placeCount++; 231 startPiece->previousPiece = piece; 232 233 if (!piece->isValid()) 234 { 235 currentPieces.remove(piece); 236 } 237#ifndef _CONTENT_PACKAGE 238 printf("Success\n"); 239#endif 240 return strongholdPiece; 241 } 242 } 243 } 244 return NULL; 245 } 246 247 StructurePiece *newPiece = generatePieceFromSmallDoor(startPiece, pieces, random, footX, footY, footZ, direction, depth + 1); 248 if (newPiece != NULL) 249 { 250 pieces->push_back(newPiece); 251 startPiece->pendingChildren.push_back(newPiece); 252 // newPiece.addChildren(startPiece, pieces, random, depth + 1); 253 } 254 return newPiece; 255} 256 257StrongholdPieces::StrongholdPiece::StrongholdPiece() 258{ 259 entryDoor = OPENING; 260 // for reflection 261} 262 263StrongholdPieces::StrongholdPiece::StrongholdPiece(int genDepth) : StructurePiece(genDepth) 264{ 265 entryDoor = OPENING; 266} 267 268void StrongholdPieces::StrongholdPiece::addAdditonalSaveData(CompoundTag *tag) 269{ 270 tag->putString(L"EntryDoor", _toString<int>(entryDoor)); 271} 272 273void StrongholdPieces::StrongholdPiece::readAdditonalSaveData(CompoundTag *tag) 274{ 275 entryDoor = (SmallDoorType)_fromString<int>(tag->getString(L"EntryDoor")); 276} 277 278void StrongholdPieces::StrongholdPiece::generateSmallDoor(Level *level, Random *random, BoundingBox *chunkBB, StrongholdPieces::StrongholdPiece::SmallDoorType doorType, int footX, int footY, int footZ) 279{ 280 switch (doorType) 281 { 282 default: 283 case OPENING: 284 generateBox(level, chunkBB, footX, footY, footZ, footX + SMALL_DOOR_WIDTH - 1, footY + SMALL_DOOR_HEIGHT - 1, footZ, 0, 0, false); 285 break; 286 case WOOD_DOOR: 287 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, chunkBB); 288 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ, chunkBB); 289 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ, chunkBB); 290 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); 291 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); 292 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); 293 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, chunkBB); 294 placeBlock(level, Tile::door_wood_Id, 0, footX + 1, footY, footZ, chunkBB); 295 placeBlock(level, Tile::door_wood_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); 296 break; 297 case GRATES: 298 placeBlock(level, 0, 0, footX + 1, footY, footZ, chunkBB); 299 placeBlock(level, 0, 0, footX + 1, footY + 1, footZ, chunkBB); 300 placeBlock(level, Tile::ironFence_Id, 0, footX, footY, footZ, chunkBB); 301 placeBlock(level, Tile::ironFence_Id, 0, footX, footY + 1, footZ, chunkBB); 302 placeBlock(level, Tile::ironFence_Id, 0, footX, footY + 2, footZ, chunkBB); 303 placeBlock(level, Tile::ironFence_Id, 0, footX + 1, footY + 2, footZ, chunkBB); 304 placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY + 2, footZ, chunkBB); 305 placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY + 1, footZ, chunkBB); 306 placeBlock(level, Tile::ironFence_Id, 0, footX + 2, footY, footZ, chunkBB); 307 break; 308 case IRON_DOOR: 309 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, chunkBB); 310 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ, chunkBB); 311 placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ, chunkBB); 312 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2, footZ, chunkBB); 313 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); 314 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); 315 placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, chunkBB); 316 placeBlock(level, Tile::door_iron_Id, 0, footX + 1, footY, footZ, chunkBB); 317 placeBlock(level, Tile::door_iron_Id, DoorTile::UPPER_BIT, footX + 1, footY + 1, footZ, chunkBB); 318 placeBlock(level, Tile::button_stone_Id, getOrientationData(Tile::button_stone_Id, 4), footX + 2, footY + 1, footZ + 1, chunkBB); 319 placeBlock(level, Tile::button_stone_Id, getOrientationData(Tile::button_stone_Id, 3), footX + 2, footY + 1, footZ - 1, chunkBB); 320 break; 321 } 322 323} 324 325StrongholdPieces::StrongholdPiece::SmallDoorType StrongholdPieces::StrongholdPiece::randomSmallDoor(Random *random) 326{ 327 int selection = random->nextInt(5); 328 switch (selection) 329 { 330 default: 331 case 0: 332 case 1: 333 return OPENING; 334 case 2: 335 return WOOD_DOOR; 336 case 3: 337 return GRATES; 338 case 4: 339 return IRON_DOOR; 340 } 341} 342 343StructurePiece *StrongholdPieces::StrongholdPiece::generateSmallDoorChildForward(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int xOff, int yOff) 344{ 345 switch (orientation) 346 { 347 case Direction::NORTH: 348 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + xOff, boundingBox->y0 + yOff, boundingBox->z0 - 1, orientation, getGenDepth()); 349 case Direction::SOUTH: 350 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + xOff, boundingBox->y0 + yOff, boundingBox->z1 + 1, orientation, getGenDepth()); 351 case Direction::WEST: 352 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + yOff, boundingBox->z0 + xOff, orientation, getGenDepth()); 353 case Direction::EAST: 354 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + yOff, boundingBox->z0 + xOff, orientation, getGenDepth()); 355 } 356 return NULL; 357} 358 359StructurePiece *StrongholdPieces::StrongholdPiece::generateSmallDoorChildLeft(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int yOff, int zOff) 360{ 361 switch (orientation) 362 { 363 case Direction::NORTH: 364 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::WEST, getGenDepth()); 365 case Direction::SOUTH: 366 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::WEST, getGenDepth()); 367 case Direction::WEST: 368 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z0 - 1, Direction::NORTH, getGenDepth()); 369 case Direction::EAST: 370 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z0 - 1, Direction::NORTH, getGenDepth()); 371 } 372 return NULL; 373} 374 375StructurePiece *StrongholdPieces::StrongholdPiece::generateSmallDoorChildRight(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int yOff, int zOff) 376{ 377 switch (orientation) 378 { 379 case Direction::NORTH: 380 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::EAST, getGenDepth()); 381 case Direction::SOUTH: 382 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::EAST, getGenDepth()); 383 case Direction::WEST: 384 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth()); 385 case Direction::EAST: 386 return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth()); 387 } 388 return NULL; 389} 390 391bool StrongholdPieces::StrongholdPiece::isOkBox(BoundingBox *box, StartPiece *startRoom) 392{ 393 //return box != NULL && box->y0 > LOWEST_Y_POSITION; 394 395 bool bIsOk = false; 396 397 if(box != NULL) 398 { 399 if( box->y0 > LOWEST_Y_POSITION ) bIsOk = true; 400 401 if( startRoom != NULL && startRoom->m_level->getOriginalSaveVersion() >= SAVE_FILE_VERSION_MOVED_STRONGHOLD ) 402 { 403 int xzSize = startRoom->m_level->getLevelData()->getXZSize(); 404 int blockMin = -( (xzSize << 4) / 2) + 1; 405 int blockMax = ( (xzSize << 4) / 2 ) - 1; 406 407 if(box->x0 <= blockMin) bIsOk = false; 408 if(box->z0 <= blockMin) bIsOk = false; 409 if(box->x1 >= blockMax) bIsOk = false; 410 if(box->z1 >= blockMax) bIsOk = false; 411 } 412 } 413 414 return bIsOk; 415} 416 417StrongholdPieces::FillerCorridor::FillerCorridor() : steps(0) 418{ 419 // for reflection 420} 421 422StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random *random, BoundingBox *corridorBox, int direction) : StrongholdPiece(genDepth), 423 steps((direction == Direction::NORTH || direction == Direction::SOUTH) ? corridorBox->getZSpan() : corridorBox->getXSpan()) 424{ 425 orientation = direction; 426 boundingBox = corridorBox; 427} 428 429void StrongholdPieces::FillerCorridor::addAdditonalSaveData(CompoundTag *tag) 430{ 431 StrongholdPiece::addAdditonalSaveData(tag); 432 tag->putInt(L"Steps", steps); 433} 434 435void StrongholdPieces::FillerCorridor::readAdditonalSaveData(CompoundTag *tag) 436{ 437 StrongholdPiece::readAdditonalSaveData(tag); 438 steps = tag->getInt(L"Steps"); 439} 440 441BoundingBox *StrongholdPieces::FillerCorridor::findPieceBox(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction) 442{ 443 const int maxLength = 3; 444 445 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5, 5, maxLength + 1, direction); 446 447 StructurePiece *collisionPiece = StructurePiece::findCollisionPiece(pieces, box); 448 449 if (collisionPiece == NULL) 450 { 451 delete box; 452 // the filler must collide with something in order to be 453 // generated 454 return NULL; 455 } 456 457 if (collisionPiece->getBoundingBox()->y0 == box->y0) 458 { 459 delete box; 460 // attempt to make a smaller piece until it fits 461 for (int depth = maxLength; depth >= 1; depth--) 462 { 463 box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5, 5, depth - 1, direction); 464 if (!collisionPiece->getBoundingBox()->intersects(box)) 465 { 466 delete box; 467 // the corridor has shrunk enough to fit, but make it 468 // one step too big to build an entrance into the other block 469 return BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5, 5, depth, direction); 470 } 471 delete box; 472 } 473 } 474 475 return NULL; 476} 477 478bool StrongholdPieces::FillerCorridor::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 479{ 480 if (edgesLiquid(level, chunkBB)) 481 { 482 return false; 483 } 484 485 // filler corridor 486 for (int i = 0; i < steps; i++) 487 { 488 // row 0 489 placeBlock(level, Tile::stoneBrick_Id, 0, 0, 0, i, chunkBB); 490 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 0, i, chunkBB); 491 placeBlock(level, Tile::stoneBrick_Id, 0, 2, 0, i, chunkBB); 492 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 0, i, chunkBB); 493 placeBlock(level, Tile::stoneBrick_Id, 0, 4, 0, i, chunkBB); 494 // row 1-3 495 for (int y = 1; y <= 3; y++) 496 { 497 placeBlock(level, Tile::stoneBrick_Id, 0, 0, y, i, chunkBB); 498 placeBlock(level, 0, 0, 1, y, i, chunkBB); 499 placeBlock(level, 0, 0, 2, y, i, chunkBB); 500 placeBlock(level, 0, 0, 3, y, i, chunkBB); 501 placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, i, chunkBB); 502 } 503 // row 4 504 placeBlock(level, Tile::stoneBrick_Id, 0, 0, 4, i, chunkBB); 505 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, i, chunkBB); 506 placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, i, chunkBB); 507 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 4, i, chunkBB); 508 placeBlock(level, Tile::stoneBrick_Id, 0, 4, 4, i, chunkBB); 509 } 510 511 return true; 512} 513 514StrongholdPieces::StairsDown::StairsDown() 515{ 516 // for reflection 517} 518 519StrongholdPieces::StairsDown::StairsDown(int genDepth, Random *random, int west, int north) : StrongholdPiece(genDepth), isSource(true) 520{ 521 orientation = random->nextInt(4); 522 entryDoor = OPENING; 523 524 switch (orientation) 525 { 526 case Direction::NORTH: 527 case Direction::SOUTH: 528 boundingBox = new BoundingBox(west, 64, north, west + width - 1, 64 + height - 1, north + depth - 1); 529 break; 530 default: 531 boundingBox = new BoundingBox(west, 64, north, west + depth - 1, 64 + height - 1, north + width - 1); 532 break; 533 } 534} 535 536StrongholdPieces::StairsDown::StairsDown(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth), isSource(false) 537{ 538 entryDoor = randomSmallDoor(random); 539 orientation = direction; 540 boundingBox = stairsBox; 541} 542 543void StrongholdPieces::StairsDown::addAdditonalSaveData(CompoundTag *tag) 544{ 545 StrongholdPiece::addAdditonalSaveData(tag); 546 tag->putBoolean(L"Source", isSource); 547} 548 549void StrongholdPieces::StairsDown::readAdditonalSaveData(CompoundTag *tag) 550{ 551 StrongholdPiece::readAdditonalSaveData(tag); 552 isSource = tag->getBoolean(L"Source"); 553} 554 555void StrongholdPieces::StairsDown::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 556{ 557 if( isSource ) 558 { 559 imposedPiece = EPieceClass_FiveCrossing; 560 } 561 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 1, 1); 562} 563 564StrongholdPieces::StairsDown *StrongholdPieces::StairsDown::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 565{ 566 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, 4 - height, 0, width, height, depth, direction); 567 568 StartPiece *startPiece = NULL; 569 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 570 571 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 572 { 573 delete box; 574 return NULL; 575 } 576 577 return new StairsDown(genDepth, random, box, direction); 578} 579 580bool StrongholdPieces::StairsDown::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 581{ 582 if (edgesLiquid(level, chunkBB)) 583 { 584 return false; 585 } 586 587 // bounding walls 588 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 589 // entry door 590 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 591 // exit door 592 generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); 593 594 // stair steps 595 placeBlock(level, Tile::stoneBrick_Id, 0, 2, 6, 1, chunkBB); 596 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 1, chunkBB); 597 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 6, 1, chunkBB); 598 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 2, chunkBB); 599 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, 3, chunkBB); 600 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 5, 3, chunkBB); 601 placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, 3, chunkBB); 602 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 3, chunkBB); 603 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 4, 3, chunkBB); 604 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 2, chunkBB); 605 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 2, 1, chunkBB); 606 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 3, 1, chunkBB); 607 placeBlock(level, Tile::stoneBrick_Id, 0, 2, 2, 1, chunkBB); 608 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 1, chunkBB); 609 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 2, 1, chunkBB); 610 placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 2, chunkBB); 611 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 1, 3, chunkBB); 612 613 return true; 614} 615 616StrongholdPieces::StartPiece::StartPiece() 617{ 618 // for reflection 619} 620 621StrongholdPieces::StartPiece::StartPiece(int genDepth, Random *random, int west, int north, Level *level) : StairsDown(0, random, west, north) 622{ 623 // 4J added initialisers 624 isLibraryAdded = false; 625 previousPiece = NULL; 626 portalRoomPiece = NULL; 627 628 m_level = level; 629} 630 631TilePos *StrongholdPieces::StartPiece::getLocatorPosition() 632{ 633 if( portalRoomPiece != NULL ) 634 { 635 return portalRoomPiece->getLocatorPosition(); 636 } 637 return StairsDown::getLocatorPosition(); 638} 639 640StrongholdPieces::Straight::Straight() 641{ 642 // for reflection 643} 644 645StrongholdPieces::Straight::Straight(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth), 646 leftChild(random->nextInt(2) == 0), 647 rightChild(random->nextInt(2) == 0) 648{ 649 entryDoor = randomSmallDoor(random); 650 orientation = direction; 651 boundingBox = stairsBox; 652} 653 654void StrongholdPieces::Straight::addAdditonalSaveData(CompoundTag *tag) 655{ 656 StrongholdPiece::addAdditonalSaveData(tag); 657 tag->putBoolean(L"Left", leftChild); 658 tag->putBoolean(L"Right", rightChild); 659} 660 661void StrongholdPieces::Straight::readAdditonalSaveData(CompoundTag *tag) 662{ 663 StrongholdPiece::readAdditonalSaveData(tag); 664 leftChild = tag->getBoolean(L"Left"); 665 rightChild = tag->getBoolean(L"Right"); 666} 667 668void StrongholdPieces::Straight::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 669{ 670 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 1, 1); 671 if (leftChild) generateSmallDoorChildLeft((StartPiece *) startPiece, pieces, random, 1, 2); 672 if (rightChild) generateSmallDoorChildRight((StartPiece *) startPiece, pieces, random, 1, 2); 673} 674 675StrongholdPieces::Straight *StrongholdPieces::Straight::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 676{ 677 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, width, height, depth, direction); 678 679 StartPiece *startPiece = NULL; 680 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 681 682 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 683 { 684 delete box; 685 return NULL; 686 } 687 688 return new Straight(genDepth, random, box, direction); 689} 690 691bool StrongholdPieces::Straight::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 692{ 693 if (edgesLiquid(level, chunkBB)) 694 { 695 return false; 696 } 697 698 // bounding walls 699 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 700 // entry door 701 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 702 // exit door 703 generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); 704 705 maybeGenerateBlock(level, chunkBB, random, .1f, 1, 2, 1, Tile::torch_Id, 0); 706 maybeGenerateBlock(level, chunkBB, random, .1f, 3, 2, 1, Tile::torch_Id, 0); 707 maybeGenerateBlock(level, chunkBB, random, .1f, 1, 2, 5, Tile::torch_Id, 0); 708 maybeGenerateBlock(level, chunkBB, random, .1f, 3, 2, 5, Tile::torch_Id, 0); 709 710 if (leftChild) 711 { 712 generateBox(level, chunkBB, 0, 1, 2, 0, 3, 4, 0, 0, false); 713 } 714 if (rightChild) 715 { 716 generateBox(level, chunkBB, 4, 1, 2, 4, 3, 4, 0, 0, false); 717 } 718 719 return true; 720} 721 722WeighedTreasure *StrongholdPieces::ChestCorridor::treasureItems[TREASURE_ITEMS_COUNT] = 723{ 724 new WeighedTreasure(Item::enderPearl_Id, 0, 1, 1, 10), 725 new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3), 726 new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), 727 new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5), 728 new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5), 729 new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15), 730 new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15), 731 new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 5), 732 new WeighedTreasure(Item::sword_iron_Id, 0, 1, 1, 5), 733 new WeighedTreasure(Item::chestplate_iron_Id, 0, 1, 1, 5), 734 new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5), 735 new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5), 736 new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5), 737 new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1), 738 // very rare for strongholds ... 739 new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 1), 740 new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1), 741 new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1), 742 new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1), 743 // ... 744}; 745 746StrongholdPieces::ChestCorridor::ChestCorridor() 747{ 748 // for reflection 749} 750 751StrongholdPieces::ChestCorridor::ChestCorridor(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth) 752{ 753 entryDoor = randomSmallDoor(random); 754 orientation = direction; 755 boundingBox = stairsBox; 756} 757 758void StrongholdPieces::ChestCorridor::addAdditonalSaveData(CompoundTag *tag) 759{ 760 StrongholdPiece::addAdditonalSaveData(tag); 761 tag->putBoolean(L"Chest", hasPlacedChest); 762} 763 764void StrongholdPieces::ChestCorridor::readAdditonalSaveData(CompoundTag *tag) 765{ 766 StrongholdPiece::readAdditonalSaveData(tag); 767 hasPlacedChest = tag->getBoolean(L"Chest"); 768} 769 770void StrongholdPieces::ChestCorridor::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 771{ 772 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 1, 1); 773} 774 775StrongholdPieces::ChestCorridor *StrongholdPieces::ChestCorridor::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 776{ 777 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, width, height, depth, direction); 778 779 StartPiece *startPiece = NULL; 780 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 781 782 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 783 { 784 delete box; 785 return NULL; 786 } 787 788 return new ChestCorridor(genDepth, random, box, direction); 789} 790 791bool StrongholdPieces::ChestCorridor::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 792{ 793 if (edgesLiquid(level, chunkBB)) 794 { 795 return false; 796 } 797 798 // bounding walls 799 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 800 // entry door 801 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 802 // exit door 803 generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); 804 805 // chest placement 806 generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrick_Id, Tile::stoneBrick_Id, false); 807 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 1, chunkBB); 808 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 5, chunkBB); 809 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 2, chunkBB); 810 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 2, 4, chunkBB); 811 for (int z = 2; z <= 4; z++) 812 { 813 placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 2, 1, z, chunkBB); 814 } 815 816 if (!hasPlacedChest) 817 { 818 int y = getWorldY(2); 819 int x = getWorldX(3, 3), z = getWorldZ(3, 3); 820 if (chunkBB->isInside(x, y, z)) 821 { 822 hasPlacedChest = true; 823 createChest(level, chunkBB, random, 3, 2, 3, WeighedTreasure::addToTreasure(WeighedTreasureArray(treasureItems,TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(2)); 824 } 825 } 826 827 return true; 828} 829 830StrongholdPieces::StraightStairsDown::StraightStairsDown() 831{ 832 // for reflection 833} 834 835StrongholdPieces::StraightStairsDown::StraightStairsDown(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth) 836{ 837 entryDoor = randomSmallDoor(random); 838 orientation = direction; 839 boundingBox = stairsBox; 840} 841 842void StrongholdPieces::StraightStairsDown::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 843{ 844 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 1, 1); 845} 846 847StrongholdPieces::StraightStairsDown *StrongholdPieces::StraightStairsDown::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 848{ 849 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, 4 - height, 0, width, height, depth, direction); 850 851 StartPiece *startPiece = NULL; 852 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 853 854 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 855 { 856 delete box; 857 return NULL; 858 } 859 860 return new StraightStairsDown(genDepth, random, box, direction); 861} 862 863bool StrongholdPieces::StraightStairsDown::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 864{ 865 if (edgesLiquid(level, chunkBB)) 866 { 867 return false; 868 } 869 870 // bounding walls 871 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 872 // entry door 873 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 874 // exit door 875 generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); 876 877 // stairs 878 int orientationData = getOrientationData(Tile::stairs_stone_Id, 2); 879 for (int i = 0; i < 6; i++) 880 { 881 placeBlock(level, Tile::stairs_stone_Id, orientationData, 1, height - 5 - i, 1 + i, chunkBB); 882 placeBlock(level, Tile::stairs_stone_Id, orientationData, 2, height - 5 - i, 1 + i, chunkBB); 883 placeBlock(level, Tile::stairs_stone_Id, orientationData, 3, height - 5 - i, 1 + i, chunkBB); 884 if (i < 5) 885 { 886 placeBlock(level, Tile::stoneBrick_Id, 0, 1, height - 6 - i, 1 + i, chunkBB); 887 placeBlock(level, Tile::stoneBrick_Id, 0, 2, height - 6 - i, 1 + i, chunkBB); 888 placeBlock(level, Tile::stoneBrick_Id, 0, 3, height - 6 - i, 1 + i, chunkBB); 889 } 890 } 891 892 return true; 893} 894 895StrongholdPieces::LeftTurn::LeftTurn() 896{ 897 // for reflection 898} 899 900StrongholdPieces::LeftTurn::LeftTurn(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth) 901{ 902 entryDoor = randomSmallDoor(random); 903 orientation = direction; 904 boundingBox = stairsBox; 905} 906 907void StrongholdPieces::LeftTurn::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 908{ 909 if (orientation == Direction::NORTH || orientation == Direction::EAST) 910 { 911 generateSmallDoorChildLeft((StartPiece *) startPiece, pieces, random, 1, 1); 912 } 913 else 914 { 915 generateSmallDoorChildRight((StartPiece *) startPiece, pieces, random, 1, 1); 916 } 917} 918 919StrongholdPieces::LeftTurn *StrongholdPieces::LeftTurn::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 920{ 921 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, width, height, depth, direction); 922 923 StartPiece *startPiece = NULL; 924 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 925 926 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 927 { 928 delete box; 929 return NULL; 930 } 931 932 return new LeftTurn(genDepth, random, box, direction); 933} 934 935bool StrongholdPieces::LeftTurn::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 936{ 937 if (edgesLiquid(level, chunkBB)) 938 { 939 return false; 940 } 941 942 // bounding walls 943 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 944 // entry door 945 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 946 // exit opening 947 if (orientation == Direction::NORTH || orientation == Direction::EAST) 948 { 949 generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, 0, 0, false); 950 } 951 else 952 { 953 generateBox(level, chunkBB, 4, 1, 1, 4, 3, 3, 0, 0, false); 954 } 955 956 return true; 957} 958 959StrongholdPieces::RightTurn::RightTurn() 960{ 961 // for reflection 962} 963 964StrongholdPieces::RightTurn::RightTurn(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : LeftTurn(genDepth, random, stairsBox, direction) 965{ 966} 967 968void StrongholdPieces::RightTurn::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 969{ 970 if (orientation == Direction::NORTH || orientation == Direction::EAST) 971 { 972 generateSmallDoorChildRight((StartPiece *) startPiece, pieces, random, 1, 1); 973 } 974 else 975 { 976 generateSmallDoorChildLeft((StartPiece *) startPiece, pieces, random, 1, 1); 977 } 978} 979 980bool StrongholdPieces::RightTurn::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 981{ 982 if (edgesLiquid(level, chunkBB)) 983 { 984 return false; 985 } 986 987 // bounding walls 988 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 989 // entry door 990 generateSmallDoor(level, random, chunkBB, entryDoor, 1, height - SMALL_DOOR_HEIGHT - 1, 0); 991 // exit opening 992 if (orientation == Direction::NORTH || orientation == Direction::EAST) 993 { 994 generateBox(level, chunkBB, 4, 1, 1, 4, 3, 3, 0, 0, false); 995 } 996 else 997 { 998 generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, 0, 0, false); 999 } 1000 1001 return true; 1002} 1003 1004StrongholdPieces::RoomCrossing::RoomCrossing() 1005{ 1006 // for reflection 1007} 1008 1009StrongholdPieces::RoomCrossing::RoomCrossing(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth), type(random->nextInt(5)) 1010{ 1011 entryDoor = randomSmallDoor(random); 1012 orientation = direction; 1013 boundingBox = stairsBox; 1014} 1015 1016void StrongholdPieces::RoomCrossing::addAdditonalSaveData(CompoundTag *tag) 1017{ 1018 StrongholdPiece::addAdditonalSaveData(tag); 1019 tag->putInt(L"Type", type); 1020} 1021 1022void StrongholdPieces::RoomCrossing::readAdditonalSaveData(CompoundTag *tag) 1023{ 1024 StrongholdPiece::readAdditonalSaveData(tag); 1025 type = tag->getInt(L"Type"); 1026} 1027 1028void StrongholdPieces::RoomCrossing::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 1029{ 1030 generateSmallDoorChildForward((StartPiece*) startPiece, pieces, random, 4, 1); 1031 generateSmallDoorChildLeft((StartPiece*) startPiece, pieces, random, 1, 4); 1032 generateSmallDoorChildRight((StartPiece*) startPiece, pieces, random, 1, 4); 1033} 1034 1035StrongholdPieces::RoomCrossing *StrongholdPieces::RoomCrossing::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 1036{ 1037 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -4, -1, 0, width, height, depth, direction); 1038 1039 StartPiece *startPiece = NULL; 1040 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 1041 1042 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1043 { 1044 delete box; 1045 return NULL; 1046 } 1047 1048 return new RoomCrossing(genDepth, random, box, direction); 1049} 1050 1051WeighedTreasure *StrongholdPieces::RoomCrossing::smallTreasureItems[SMALL_TREASURE_ITEMS_COUNT] = 1052{ 1053 new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10), 1054 new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5), 1055 new WeighedTreasure(Item::redStone_Id, 0, 4, 9, 5), 1056 new WeighedTreasure(Item::coal_Id, CoalItem::STONE_COAL, 3, 8, 10), 1057 new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15), 1058 new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15), 1059 new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 1), 1060}; 1061 1062bool StrongholdPieces::RoomCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 1063{ 1064 if (edgesLiquid(level, chunkBB)) 1065 { 1066 return false; 1067 } 1068 1069 // bounding walls 1070 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 1071 // entry door 1072 generateSmallDoor(level, random, chunkBB, entryDoor, 4, 1, 0); 1073 // exit openings 1074 generateBox(level, chunkBB, 4, 1, depth - 1, 6, 3, depth - 1, 0, 0, false); 1075 generateBox(level, chunkBB, 0, 1, 4, 0, 3, 6, 0, 0, false); 1076 generateBox(level, chunkBB, width - 1, 1, 4, width - 1, 3, 6, 0, 0, false); 1077 1078 switch (type) 1079 { 1080 default: 1081 break; 1082 case 0: 1083 // middle torch pillar 1084 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); 1085 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB); 1086 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB); 1087 placeBlock(level, Tile::torch_Id, 0, 4, 3, 5, chunkBB); 1088 placeBlock(level, Tile::torch_Id, 0, 6, 3, 5, chunkBB); 1089 placeBlock(level, Tile::torch_Id, 0, 5, 3, 4, chunkBB); 1090 placeBlock(level, Tile::torch_Id, 0, 5, 3, 6, chunkBB); 1091 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 4, chunkBB); 1092 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 5, chunkBB); 1093 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 4, 1, 6, chunkBB); 1094 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 4, chunkBB); 1095 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 5, chunkBB); 1096 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 6, 1, 6, chunkBB); 1097 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 5, 1, 4, chunkBB); 1098 placeBlock(level, Tile::stoneSlabHalf_Id, 0, 5, 1, 6, chunkBB); 1099 break; 1100 case 1: 1101 { 1102 for (int i = 0; i < 5; i++) 1103 { 1104 placeBlock(level, Tile::stoneBrick_Id, 0, 3, 1, 3 + i, chunkBB); 1105 placeBlock(level, Tile::stoneBrick_Id, 0, 7, 1, 3 + i, chunkBB); 1106 placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 3, chunkBB); 1107 placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 7, chunkBB); 1108 } 1109 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); 1110 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB); 1111 placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB); 1112 placeBlock(level, Tile::water_Id, 0, 5, 4, 5, chunkBB); 1113 } 1114 break; 1115 case 2: 1116 { 1117 for (int z = 1; z <= 9; z++) 1118 { 1119 placeBlock(level, Tile::cobblestone_Id, 0, 1, 3, z, chunkBB); 1120 placeBlock(level, Tile::cobblestone_Id, 0, 9, 3, z, chunkBB); 1121 } 1122 for (int x = 1; x <= 9; x++) 1123 { 1124 placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 1, chunkBB); 1125 placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 9, chunkBB); 1126 } 1127 placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 4, chunkBB); 1128 placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 6, chunkBB); 1129 placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 4, chunkBB); 1130 placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 6, chunkBB); 1131 placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 5, chunkBB); 1132 placeBlock(level, Tile::cobblestone_Id, 0, 6, 1, 5, chunkBB); 1133 placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 5, chunkBB); 1134 placeBlock(level, Tile::cobblestone_Id, 0, 6, 3, 5, chunkBB); 1135 for (int y = 1; y <= 3; y++) 1136 { 1137 placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 4, chunkBB); 1138 placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 4, chunkBB); 1139 placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 6, chunkBB); 1140 placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 6, chunkBB); 1141 } 1142 placeBlock(level, Tile::torch_Id, 0, 5, 3, 5, chunkBB); 1143 for (int z = 2; z <= 8; z++) 1144 { 1145 placeBlock(level, Tile::wood_Id, 0, 2, 3, z, chunkBB); 1146 placeBlock(level, Tile::wood_Id, 0, 3, 3, z, chunkBB); 1147 if (z <= 3 || z >= 7) 1148 { 1149 placeBlock(level, Tile::wood_Id, 0, 4, 3, z, chunkBB); 1150 placeBlock(level, Tile::wood_Id, 0, 5, 3, z, chunkBB); 1151 placeBlock(level, Tile::wood_Id, 0, 6, 3, z, chunkBB); 1152 } 1153 placeBlock(level, Tile::wood_Id, 0, 7, 3, z, chunkBB); 1154 placeBlock(level, Tile::wood_Id, 0, 8, 3, z, chunkBB); 1155 } 1156 placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 1, 3, chunkBB); 1157 placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 2, 3, chunkBB); 1158 placeBlock(level, Tile::ladder_Id, getOrientationData(Tile::ladder_Id, Facing::WEST), 9, 3, 3, chunkBB); 1159 1160 createChest(level, chunkBB, random, 3, 4, 8, WeighedTreasure::addToTreasure(WeighedTreasureArray(smallTreasureItems,SMALL_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random)), 1 + random->nextInt(4)); 1161 // System.out.println("Created chest at " + getWorldX(3, 8) + 1162 // "," + getWorldY(4) + "," + getWorldZ(3, 8)); 1163 1164 } 1165 break; 1166 } 1167 return true; 1168} 1169 1170StrongholdPieces::PrisonHall::PrisonHall() 1171{ 1172 // for reflection 1173} 1174 1175StrongholdPieces::PrisonHall::PrisonHall(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth) 1176{ 1177 entryDoor = randomSmallDoor(random); 1178 orientation = direction; 1179 boundingBox = stairsBox; 1180} 1181 1182void StrongholdPieces::PrisonHall::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 1183{ 1184 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 1, 1); 1185} 1186 1187StrongholdPieces::PrisonHall *StrongholdPieces::PrisonHall::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 1188{ 1189 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, width, height, depth, direction); 1190 1191 StartPiece *startPiece = NULL; 1192 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 1193 1194 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1195 { 1196 delete box; 1197 return NULL; 1198 } 1199 1200 return new PrisonHall(genDepth, random, box, direction); 1201} 1202 1203bool StrongholdPieces::PrisonHall::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 1204{ 1205 if (edgesLiquid(level, chunkBB)) 1206 { 1207 return false; 1208 } 1209 1210 // bounding walls 1211 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 1212 // entry door 1213 generateSmallDoor(level, random, chunkBB, entryDoor, 1, 1, 0); 1214 // exit openings 1215 generateBox(level, chunkBB, 1, 1, depth - 1, 3, 3, depth - 1, 0, 0, false); 1216 1217 // door pillars 1218 generateBox(level, chunkBB, 4, 1, 1, 4, 3, 1, false, random, (BlockSelector *)smoothStoneSelector); 1219 generateBox(level, chunkBB, 4, 1, 3, 4, 3, 3, false, random, (BlockSelector *)smoothStoneSelector); 1220 generateBox(level, chunkBB, 4, 1, 7, 4, 3, 7, false, random, (BlockSelector *)smoothStoneSelector); 1221 generateBox(level, chunkBB, 4, 1, 9, 4, 3, 9, false, random, (BlockSelector *)smoothStoneSelector); 1222 1223 // grates 1224 generateBox(level, chunkBB, 4, 1, 4, 4, 3, 6, Tile::ironFence_Id, Tile::ironFence_Id, false); 1225 generateBox(level, chunkBB, 5, 1, 5, 7, 3, 5, Tile::ironFence_Id, Tile::ironFence_Id, false); 1226 1227 // doors 1228 placeBlock(level, Tile::ironFence_Id, 0, 4, 3, 2, chunkBB); 1229 placeBlock(level, Tile::ironFence_Id, 0, 4, 3, 8, chunkBB); 1230 placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3), 4, 1, 2, chunkBB); 1231 placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 2, chunkBB); 1232 placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3), 4, 1, 8, chunkBB); 1233 placeBlock(level, Tile::door_iron_Id, getOrientationData(Tile::door_iron_Id, 3) + DoorTile::UPPER_BIT, 4, 2, 8, chunkBB); 1234 1235 return true; 1236 1237} 1238 1239StrongholdPieces::Library::Library() 1240{ 1241 isTall = false; 1242 // for reflection 1243} 1244 1245StrongholdPieces::Library::Library(int genDepth, Random *random, BoundingBox *roomBox, int direction) : StrongholdPiece(genDepth), 1246 isTall(roomBox->getYSpan() > height) 1247{ 1248 entryDoor = randomSmallDoor(random); 1249 orientation = direction; 1250 boundingBox = roomBox; 1251} 1252 1253void StrongholdPieces::Library::addAdditonalSaveData(CompoundTag *tag) 1254{ 1255 StrongholdPiece::addAdditonalSaveData(tag); 1256 tag->putBoolean(L"Tall", isTall); 1257} 1258 1259void StrongholdPieces::Library::readAdditonalSaveData(CompoundTag *tag) 1260{ 1261 StrongholdPiece::readAdditonalSaveData(tag); 1262 isTall = tag->getBoolean(L"Tall"); 1263} 1264 1265StrongholdPieces::Library *StrongholdPieces::Library::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 1266{ 1267 // attempt to make a tall library first 1268 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -4, -1, 0, width, tallHeight, depth, direction); 1269 1270 StartPiece *startPiece = NULL; 1271 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 1272 1273 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1274 { 1275 delete box; 1276 // make a short library 1277 box = BoundingBox::orientBox(footX, footY, footZ, -4, -1, 0, width, height, depth, direction); 1278 1279 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1280 { 1281 delete box; 1282 return NULL; 1283 } 1284 } 1285 1286 return new Library(genDepth, random, box, direction); 1287} 1288 1289WeighedTreasure *StrongholdPieces::Library::libraryTreasureItems[LIBRARY_TREASURE_ITEMS_COUNT] = 1290{ 1291 new WeighedTreasure(Item::book_Id, 0, 1, 3, 20), 1292 new WeighedTreasure(Item::paper_Id, 0, 2, 7, 20), 1293 new WeighedTreasure(Item::map_Id, 0, 1, 1, 1), 1294 new WeighedTreasure(Item::compass_Id, 0, 1, 1, 1), 1295}; 1296 1297bool StrongholdPieces::Library::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 1298{ 1299 if (edgesLiquid(level, chunkBB)) 1300 { 1301 return false; 1302 } 1303 1304 int currentHeight = tallHeight; 1305 if (!isTall) 1306 { 1307 currentHeight = height; 1308 } 1309 1310 // bounding walls 1311 generateBox(level, chunkBB, 0, 0, 0, width - 1, currentHeight - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 1312 // entry door 1313 generateSmallDoor(level, random, chunkBB, entryDoor, 4, 1, 0); 1314 1315 // place sparse cob webs 1316 generateMaybeBox(level, chunkBB, random, .07f, 2, 1, 1, width - 1 - 2, height - 2, depth - 2, Tile::web_Id, Tile::web_Id, false); 1317 1318 const int bookLeft = 1; 1319 const int bookRight = width - 2; 1320 1321 // place library walls 1322 for (int d = 1; d <= depth - 2; d++) { 1323 if (((d - 1) % 4) == 0) { 1324 generateBox(level, chunkBB, bookLeft, 1, d, bookLeft, 4, d, Tile::wood_Id, Tile::wood_Id, false); 1325 generateBox(level, chunkBB, bookRight, 1, d, bookRight, 4, d, Tile::wood_Id, Tile::wood_Id, false); 1326 1327 placeBlock(level, Tile::torch_Id, 0, 2, 3, d, chunkBB); 1328 placeBlock(level, Tile::torch_Id, 0, width - 3, 3, d, chunkBB); 1329 1330 if (isTall) 1331 { 1332 generateBox(level, chunkBB, bookLeft, 6, d, bookLeft, 9, d, Tile::wood_Id, Tile::wood_Id, false); 1333 generateBox(level, chunkBB, bookRight, 6, d, bookRight, 9, d, Tile::wood_Id, Tile::wood_Id, false); 1334 } 1335 } 1336 else 1337 { 1338 generateBox(level, chunkBB, bookLeft, 1, d, bookLeft, 4, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1339 generateBox(level, chunkBB, bookRight, 1, d, bookRight, 4, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1340 1341 if (isTall) 1342 { 1343 generateBox(level, chunkBB, bookLeft, 6, d, bookLeft, 9, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1344 generateBox(level, chunkBB, bookRight, 6, d, bookRight, 9, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1345 } 1346 } 1347 } 1348 1349 // place book shelves 1350 for (int d = 3; d < depth - 3; d += 2) 1351 { 1352 generateBox(level, chunkBB, 3, 1, d, 4, 3, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1353 generateBox(level, chunkBB, 6, 1, d, 7, 3, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1354 generateBox(level, chunkBB, 9, 1, d, 10, 3, d, Tile::bookshelf_Id, Tile::bookshelf_Id, false); 1355 } 1356 1357 if (isTall) 1358 { 1359 // create balcony 1360 generateBox(level, chunkBB, 1, 5, 1, 3, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); 1361 generateBox(level, chunkBB, width - 4, 5, 1, width - 2, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); 1362 generateBox(level, chunkBB, 4, 5, 1, width - 5, 5, 2, Tile::wood_Id, Tile::wood_Id, false); 1363 generateBox(level, chunkBB, 4, 5, depth - 3, width - 5, 5, depth - 2, Tile::wood_Id, Tile::wood_Id, false); 1364 1365 placeBlock(level, Tile::wood_Id, 0, width - 5, 5, depth - 4, chunkBB); 1366 placeBlock(level, Tile::wood_Id, 0, width - 6, 5, depth - 4, chunkBB); 1367 placeBlock(level, Tile::wood_Id, 0, width - 5, 5, depth - 5, chunkBB); 1368 1369 // balcony fences 1370 generateBox(level, chunkBB, 3, 6, 2, 3, 6, depth - 3, Tile::fence_Id, Tile::fence_Id, false); 1371 generateBox(level, chunkBB, width - 4, 6, 2, width - 4, 6, depth - 5, Tile::fence_Id, Tile::fence_Id, false); 1372 generateBox(level, chunkBB, 4, 6, 2, width - 5, 6, 2, Tile::fence_Id, Tile::fence_Id, false); 1373 generateBox(level, chunkBB, 4, 6, depth - 3, 8, 6, depth - 3, Tile::fence_Id, Tile::fence_Id, false); 1374 placeBlock(level, Tile::fence_Id, 0, width - 5, 6, depth - 4, chunkBB); 1375 placeBlock(level, Tile::fence_Id, 0, width - 6, 6, depth - 4, chunkBB); 1376 placeBlock(level, Tile::fence_Id, 0, width - 5, 6, depth - 5, chunkBB); 1377 1378 // ladder 1379 int orientationData = getOrientationData(Tile::ladder_Id, 3); 1380 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 1, depth - 2, chunkBB); 1381 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 2, depth - 2, chunkBB); 1382 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 3, depth - 2, chunkBB); 1383 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 4, depth - 2, chunkBB); 1384 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 5, depth - 2, chunkBB); 1385 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 6, depth - 2, chunkBB); 1386 placeBlock(level, Tile::ladder_Id, orientationData, width - 4, 7, depth - 2, chunkBB); 1387 1388 // chandelier 1389 int x = width / 2; 1390 int z = depth / 2; 1391 placeBlock(level, Tile::fence_Id, 0, x - 1, tallHeight - 2, z, chunkBB); 1392 placeBlock(level, Tile::fence_Id, 0, x, tallHeight - 2, z, chunkBB); 1393 placeBlock(level, Tile::fence_Id, 0, x - 1, tallHeight - 3, z, chunkBB); 1394 placeBlock(level, Tile::fence_Id, 0, x, tallHeight - 3, z, chunkBB); 1395 placeBlock(level, Tile::fence_Id, 0, x - 1, tallHeight - 4, z, chunkBB); 1396 placeBlock(level, Tile::fence_Id, 0, x, tallHeight - 4, z, chunkBB); 1397 1398 placeBlock(level, Tile::fence_Id, 0, x - 2, tallHeight - 4, z, chunkBB); 1399 placeBlock(level, Tile::fence_Id, 0, x + 1, tallHeight - 4, z, chunkBB); 1400 placeBlock(level, Tile::fence_Id, 0, x - 1, tallHeight - 4, z - 1, chunkBB); 1401 placeBlock(level, Tile::fence_Id, 0, x - 1, tallHeight - 4, z + 1, chunkBB); 1402 placeBlock(level, Tile::fence_Id, 0, x, tallHeight - 4, z - 1, chunkBB); 1403 placeBlock(level, Tile::fence_Id, 0, x, tallHeight - 4, z + 1, chunkBB); 1404 1405 placeBlock(level, Tile::torch_Id, 0, x - 2, tallHeight - 3, z, chunkBB); 1406 placeBlock(level, Tile::torch_Id, 0, x + 1, tallHeight - 3, z, chunkBB); 1407 placeBlock(level, Tile::torch_Id, 0, x - 1, tallHeight - 3, z - 1, chunkBB); 1408 placeBlock(level, Tile::torch_Id, 0, x - 1, tallHeight - 3, z + 1, chunkBB); 1409 placeBlock(level, Tile::torch_Id, 0, x, tallHeight - 3, z - 1, chunkBB); 1410 placeBlock(level, Tile::torch_Id, 0, x, tallHeight - 3, z + 1, chunkBB); 1411 } 1412 1413 // place chests 1414 createChest(level, chunkBB, random, 3, 3, 5, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); 1415 if (isTall) 1416 { 1417 placeBlock(level, 0, 0, width - 2, tallHeight - 2, 1, chunkBB); 1418 createChest(level, chunkBB, random, width - 2, tallHeight - 3, 1, WeighedTreasure::addToTreasure(WeighedTreasureArray(libraryTreasureItems,LIBRARY_TREASURE_ITEMS_COUNT), Item::enchantedBook->createForRandomTreasure(random, 1, 5, 2)), 1 + random->nextInt(4)); 1419 } 1420 1421 return true; 1422 1423} 1424 1425StrongholdPieces::FiveCrossing::FiveCrossing() 1426{ 1427 leftLow = leftHigh = rightLow = rightHigh = false; 1428 // for reflection 1429} 1430 1431StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random *random, BoundingBox *stairsBox, int direction) : StrongholdPiece(genDepth) 1432{ 1433 entryDoor = randomSmallDoor(random); 1434 orientation = direction; 1435 boundingBox = stairsBox; 1436 1437 leftLow = random->nextBoolean(); 1438 leftHigh = random->nextBoolean(); 1439 rightLow = random->nextBoolean(); 1440 rightHigh = random->nextInt(3) > 0; 1441} 1442 1443void StrongholdPieces::FiveCrossing::addAdditonalSaveData(CompoundTag *tag) 1444{ 1445 StrongholdPiece::addAdditonalSaveData(tag); 1446 tag->putBoolean(L"leftLow", leftLow); 1447 tag->putBoolean(L"leftHigh", leftHigh); 1448 tag->putBoolean(L"rightLow", rightLow); 1449 tag->putBoolean(L"rightHigh", rightHigh); 1450} 1451 1452void StrongholdPieces::FiveCrossing::readAdditonalSaveData(CompoundTag *tag) 1453{ 1454 StrongholdPiece::readAdditonalSaveData(tag); 1455 leftLow = tag->getBoolean(L"leftLow"); 1456 leftHigh = tag->getBoolean(L"leftHigh"); 1457 rightLow = tag->getBoolean(L"rightLow"); 1458 rightHigh = tag->getBoolean(L"rightHigh"); 1459} 1460 1461void StrongholdPieces::FiveCrossing::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 1462{ 1463 int zOffA = 3; 1464 int zOffB = 5; 1465 // compensate for weird negative-facing behaviour 1466 if (orientation == Direction::WEST || orientation == Direction::NORTH) 1467 { 1468 zOffA = depth - 3 - zOffA; 1469 zOffB = depth - 3 - zOffB; 1470 } 1471 1472 generateSmallDoorChildForward((StartPiece *) startPiece, pieces, random, 5, 1); 1473 if (leftLow) generateSmallDoorChildLeft((StartPiece *) startPiece, pieces, random, zOffA, 1); 1474 if (leftHigh) generateSmallDoorChildLeft((StartPiece *) startPiece, pieces, random, zOffB, 7); 1475 if (rightLow) generateSmallDoorChildRight((StartPiece *) startPiece, pieces, random, zOffA, 1); 1476 if (rightHigh) generateSmallDoorChildRight((StartPiece *) startPiece, pieces, random, zOffB, 7); 1477} 1478 1479StrongholdPieces::FiveCrossing *StrongholdPieces::FiveCrossing::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 1480{ 1481 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -4, -3, 0, width, height, depth, direction); 1482 1483 StartPiece *startPiece = NULL; 1484 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 1485 1486 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1487 { 1488 delete box; 1489 return NULL; 1490 } 1491 1492 return new FiveCrossing(genDepth, random, box, direction); 1493} 1494 1495bool StrongholdPieces::FiveCrossing::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 1496{ 1497 if (edgesLiquid(level, chunkBB)) 1498 { 1499 return false; 1500 } 1501 1502 // bounding walls 1503 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, CHECK_AIR, random, (BlockSelector *)smoothStoneSelector); 1504 // entry door 1505 generateSmallDoor(level, random, chunkBB, entryDoor, 4, 3, 0); 1506 1507 // exit openings 1508 if (leftLow) generateBox(level, chunkBB, 0, 3, 1, 0, 5, 3, 0, 0, false); 1509 if (rightLow) generateBox(level, chunkBB, 9, 3, 1, 9, 5, 3, 0, 0, false); 1510 if (leftHigh) generateBox(level, chunkBB, 0, 5, 7, 0, 7, 9, 0, 0, false); 1511 if (rightHigh) generateBox(level, chunkBB, 9, 5, 7, 9, 7, 9, 0, 0, false); 1512 generateBox(level, chunkBB, 5, 1, 10, 7, 3, 10, 0, 0, false); 1513 1514 // main floor 1515 generateBox(level, chunkBB, 1, 2, 1, 8, 2, 6, false, random, (BlockSelector *)smoothStoneSelector); 1516 // side walls 1517 generateBox(level, chunkBB, 4, 1, 5, 4, 4, 9, false, random, (BlockSelector *)smoothStoneSelector); 1518 generateBox(level, chunkBB, 8, 1, 5, 8, 4, 9, false, random, (BlockSelector *)smoothStoneSelector); 1519 // upper floor 1520 generateBox(level, chunkBB, 1, 4, 7, 3, 4, 9, false, random, (BlockSelector *)smoothStoneSelector); 1521 1522 // left stairs 1523 generateBox(level, chunkBB, 1, 3, 5, 3, 3, 6, false, random, (BlockSelector *)smoothStoneSelector); 1524 generateBox(level, chunkBB, 1, 3, 4, 3, 3, 4, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1525 generateBox(level, chunkBB, 1, 4, 6, 3, 4, 6, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1526 1527 // lower stairs 1528 generateBox(level, chunkBB, 5, 1, 7, 7, 1, 8, false, random, (BlockSelector *)smoothStoneSelector); 1529 generateBox(level, chunkBB, 5, 1, 9, 7, 1, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1530 generateBox(level, chunkBB, 5, 2, 7, 7, 2, 7, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1531 1532 // bridge 1533 generateBox(level, chunkBB, 4, 5, 7, 4, 5, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1534 generateBox(level, chunkBB, 8, 5, 7, 8, 5, 9, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); 1535 generateBox(level, chunkBB, 5, 5, 7, 7, 5, 9, Tile::stoneSlab_Id, Tile::stoneSlab_Id, false); 1536 placeBlock(level, Tile::torch_Id, 0, 6, 5, 6, chunkBB); 1537 1538 return true; 1539 1540} 1541 1542StrongholdPieces::PortalRoom::PortalRoom() 1543{ 1544 // for reflection 1545} 1546 1547StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random *random, BoundingBox *box, int direction) : StrongholdPiece(genDepth) 1548{ 1549 hasPlacedMobSpawner = false; 1550 orientation = direction; 1551 boundingBox = box; 1552} 1553 1554void StrongholdPieces::PortalRoom::addAdditonalSaveData(CompoundTag *tag) 1555{ 1556 StrongholdPiece::addAdditonalSaveData(tag); 1557 tag->putBoolean(L"Mob", hasPlacedMobSpawner); 1558} 1559 1560void StrongholdPieces::PortalRoom::readAdditonalSaveData(CompoundTag *tag) 1561{ 1562 StrongholdPiece::readAdditonalSaveData(tag); 1563 hasPlacedMobSpawner = tag->getBoolean(L"Mob"); 1564} 1565 1566void StrongholdPieces::PortalRoom::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random) 1567{ 1568 if (startPiece != NULL) 1569 { 1570 ((StartPiece *) startPiece)->portalRoomPiece = this; 1571 } 1572} 1573 1574StrongholdPieces::PortalRoom *StrongholdPieces::PortalRoom::createPiece(list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth) 1575{ 1576 BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -4, -1, 0, width, height, depth, direction); 1577 1578 // 4J Added so that we can check that Portals stay within the bounds of the world (which they ALWAYS should anyway) 1579 StartPiece *startPiece = NULL; 1580 if(pieces != NULL) startPiece = ((StrongholdPieces::StartPiece *) pieces->front()); 1581 1582 if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != NULL) 1583 { 1584 delete box; 1585 return NULL; 1586 } 1587 1588 return new PortalRoom(genDepth, random, box, direction); 1589} 1590 1591bool StrongholdPieces::PortalRoom::postProcess(Level *level, Random *random, BoundingBox *chunkBB) 1592{ 1593 // bounding walls 1594 generateBox(level, chunkBB, 0, 0, 0, width - 1, height - 1, depth - 1, false, random, (BlockSelector *)smoothStoneSelector); 1595 // entry door 1596 generateSmallDoor(level, random, chunkBB, GRATES, 4, 1, 0); 1597 1598 // inner roof row 1599 int y = height - 2; 1600 generateBox(level, chunkBB, 1, y, 1, 1, y, depth - 2, false, random, (BlockSelector *)smoothStoneSelector); 1601 generateBox(level, chunkBB, width - 2, y, 1, width - 2, y, depth - 2, false, random, (BlockSelector *)smoothStoneSelector); 1602 generateBox(level, chunkBB, 2, y, 1, width - 3, y, 2, false, random, (BlockSelector *)smoothStoneSelector); 1603 generateBox(level, chunkBB, 2, y, depth - 2, width - 3, y, depth - 2, false, random, (BlockSelector *)smoothStoneSelector); 1604 1605 // entrance lava pools 1606 generateBox(level, chunkBB, 1, 1, 1, 2, 1, 4, false, random, (BlockSelector *)smoothStoneSelector); 1607 generateBox(level, chunkBB, width - 3, 1, 1, width - 2, 1, 4, false, random, (BlockSelector *)smoothStoneSelector); 1608 generateBox(level, chunkBB, 1, 1, 1, 1, 1, 3, Tile::lava_Id, Tile::lava_Id, false); 1609 generateBox(level, chunkBB, width - 2, 1, 1, width - 2, 1, 3, Tile::lava_Id, Tile::lava_Id, false); 1610 1611 // portal lava pool 1612 generateBox(level, chunkBB, 3, 1, 8, 7, 1, 12, false, random, (BlockSelector *)smoothStoneSelector); 1613 generateBox(level, chunkBB, 4, 1, 9, 6, 1, 11, Tile::lava_Id, Tile::lava_Id, false); 1614 1615 // wall decorations 1616 for (int z = 3; z < depth - 2; z += 2) 1617 { 1618 generateBox(level, chunkBB, 0, 3, z, 0, 4, z, Tile::ironFence_Id, Tile::ironFence_Id, false); 1619 generateBox(level, chunkBB, width - 1, 3, z, width - 1, 4, z, Tile::ironFence_Id, Tile::ironFence_Id, false); 1620 } 1621 for (int x = 2; x < width - 2; x += 2) 1622 { 1623 generateBox(level, chunkBB, x, 3, depth - 1, x, 4, depth - 1, Tile::ironFence_Id, Tile::ironFence_Id, false); 1624 } 1625 1626 // stair 1627 int orientationData = getOrientationData(Tile::stairs_stoneBrick_Id, 3); 1628 generateBox(level, chunkBB, 4, 1, 5, 6, 1, 7, false, random, (BlockSelector *)smoothStoneSelector); 1629 generateBox(level, chunkBB, 4, 2, 6, 6, 2, 7, false, random, (BlockSelector *)smoothStoneSelector); 1630 generateBox(level, chunkBB, 4, 3, 7, 6, 3, 7, false, random, (BlockSelector *)smoothStoneSelector); 1631 for (int x = 4; x <= 6; x++) 1632 { 1633 placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 1, 4, chunkBB); 1634 placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 2, 5, chunkBB); 1635 placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 3, 6, chunkBB); 1636 } 1637 1638 int north = Direction::NORTH; 1639 int south = Direction::SOUTH; 1640 int east = Direction::EAST; 1641 int west = Direction::WEST; 1642 1643 switch (orientation) 1644 { 1645 case Direction::SOUTH: 1646 north = Direction::SOUTH; 1647 south = Direction::NORTH; 1648 break; 1649 case Direction::EAST: 1650 north = Direction::EAST; 1651 south = Direction::WEST; 1652 east = Direction::SOUTH; 1653 west = Direction::NORTH; 1654 break; 1655 case Direction::WEST: 1656 north = Direction::WEST; 1657 south = Direction::EAST; 1658 east = Direction::SOUTH; 1659 west = Direction::NORTH; 1660 break; 1661 } 1662 1663 // 4J-PB - Removed for Christmas update since we don't have The End 1664 1665 // 4J-PB - not going to remove it, so that maps generated will have it in, but it can't be activated 1666 placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 8, chunkBB); 1667 placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 8, chunkBB); 1668 placeBlock(level, Tile::endPortalFrameTile_Id, north + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 8, chunkBB); 1669 placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 4, 3, 12, chunkBB); 1670 placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 5, 3, 12, chunkBB); 1671 placeBlock(level, Tile::endPortalFrameTile_Id, south + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 6, 3, 12, chunkBB); 1672 placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 9, chunkBB); 1673 placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 10, chunkBB); 1674 placeBlock(level, Tile::endPortalFrameTile_Id, east + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 3, 3, 11, chunkBB); 1675 placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 9, chunkBB); 1676 placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 10, chunkBB); 1677 placeBlock(level, Tile::endPortalFrameTile_Id, west + ((random->nextFloat() > 0.9f) ? TheEndPortalFrameTile::EYE_BIT : 0), 7, 3, 11, chunkBB); 1678 1679 1680 if (!hasPlacedMobSpawner) 1681 { 1682 y = getWorldY(3); 1683 int x = getWorldX(5, 6), z = getWorldZ(5, 6); 1684 if (chunkBB->isInside(x, y, z)) 1685 { 1686 // 4J Stu - The mob spawner location is close enough for the map icon display, and this ensures that we only need to set the position once 1687 app.AddTerrainFeaturePosition(eTerrainFeature_StrongholdEndPortal,x,z); 1688 level->getLevelData()->setXStrongholdEndPortal(x); 1689 level->getLevelData()->setZStrongholdEndPortal(z); 1690 level->getLevelData()->setHasStrongholdEndPortal(); 1691 1692 hasPlacedMobSpawner = true; 1693 level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, Tile::UPDATE_CLIENTS); 1694 shared_ptr<MobSpawnerTileEntity> entity = dynamic_pointer_cast<MobSpawnerTileEntity>(level->getTileEntity(x, y, z)); 1695 if (entity != NULL) entity->getSpawner()->setEntityId(L"Silverfish"); 1696 } 1697 } 1698 1699 return true; 1700 1701} 1702 1703void StrongholdPieces::SmoothStoneSelector::next(Random *random, int worldX, int worldY, int worldZ, bool isEdge) 1704{ 1705 if (isEdge) 1706 { 1707 nextId = Tile::stoneBrick_Id; 1708 1709 float selection = random->nextFloat(); 1710 if (selection < 0.2f) 1711 { 1712 nextData = SmoothStoneBrickTile::TYPE_CRACKED; 1713 } 1714 else if (selection < 0.5f) 1715 { 1716 nextData = SmoothStoneBrickTile::TYPE_MOSSY; 1717 } 1718 else if (selection < 0.55f) 1719 { 1720 nextId = Tile::monsterStoneEgg_Id; 1721 nextData = StoneMonsterTile::HOST_STONEBRICK; 1722 } 1723 else 1724 { 1725 nextData = 0; 1726 } 1727 } 1728 else 1729 { 1730 nextId = 0; 1731 nextData = 0; 1732 } 1733} 1734 1735const StrongholdPieces::SmoothStoneSelector *StrongholdPieces::smoothStoneSelector = new SmoothStoneSelector();