the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 857 lines 20 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.world.level.levelgen.structure.h" 3#include "net.minecraft.world.level.h" 4#include "net.minecraft.world.level.tile.h" 5#include "net.minecraft.world.level.material.h" 6#include "net.minecraft.world.level.tile.entity.h" 7#include "net.minecraft.world.entity.h" 8#include "WeighedTreasure.h" 9#include "StructurePiece.h" 10#include "BoundingBox.h" 11#include "Direction.h" 12#include "JavaMath.h" 13#include "Facing.h" 14#include "DoorItem.h" 15 16/** 17* 18* A structure piece is a construction or room, located somewhere in the world 19* with a given orientatino (out of Direction.java). Structure pieces have a 20* bounding box that says where the piece is located and its bounds, and the 21* orientation is used to translate local coordinates into world coordinates. 22* <p> 23* The default orientation is Direction.UNDEFINED, in which case no translation 24* will occur. If the orientation is Direction::NORTH, coordinate (0, 0, 0) will 25* be at (boundingBox.x0, boundingBox.y0, boundingBox.z1). In other words, (1, 26* 1, 1) will be translated to (boundingBox.x0 + 1, boundingBox.y0 + 1, 27* boundingBox.z1 - 1). 28* <p> 29* When using Direction::SOUTH, the x coordinate will be the same, and the z 30* coordinate will be flipped. In other words, the bounding box is NOT rotated! 31* It is only flipped along the z axis. Also note that the bounding box is in 32* world coordinates, so the local drawing must never reach outside of this. 33* <p> 34* When using east and west coordinates, the local z coordinate will be swapped 35* with the local x coordinate. For example, (0, 0, 0) is (boundingBox.z1, 36* boundingBox.y0, boundingBox.z0), and (1, 1, 1) becomes (boundingBox.x1 - 1, 37* boundingBox.y0 + 1, boundingBox.z0 + 1) when using Direction::WEST. 38* <p> 39* When-ever a structure piece is placing blocks, it is VERY IMPORTANT to always 40* make sure that all getTile and setTile calls are within the chunk's bounding 41* box. Failing to check this will cause the level generator to create new 42* chunks, leading to infinite loops and other errors. 43*/ 44 45StructurePiece::StructurePiece() 46{ 47 boundingBox = NULL; 48 orientation = 0; 49 genDepth = 0; 50 // for reflection 51} 52 53StructurePiece::StructurePiece( int genDepth ) 54{ 55 boundingBox = NULL; 56 this->genDepth = genDepth; 57 orientation = Direction::UNDEFINED; 58} 59 60StructurePiece::~StructurePiece() 61{ 62 if(boundingBox != NULL) delete boundingBox; 63} 64 65CompoundTag *StructurePiece::createTag() 66{ 67 CompoundTag *tag = new CompoundTag(); 68 69 tag->putString(L"id", StructureFeatureIO::getEncodeId(this)); 70 tag->put(L"BB", boundingBox->createTag(L"BB")); 71 tag->putInt(L"O", orientation); 72 tag->putInt(L"GD", genDepth); 73 74 addAdditonalSaveData(tag); 75 76 return tag; 77} 78 79void StructurePiece::load(Level *level, CompoundTag *tag) 80{ 81 82 if (tag->contains(L"BB")) 83 { 84 boundingBox = new BoundingBox(tag->getIntArray(L"BB")); 85 } 86 orientation = tag->getInt(L"O"); 87 genDepth = tag->getInt(L"GD"); 88 89 readAdditonalSaveData(tag); 90} 91 92void StructurePiece::addChildren( StructurePiece* startPiece, list< StructurePiece* > *pieces, Random* random ) 93{ 94} 95 96BoundingBox* StructurePiece::getBoundingBox() 97{ 98 return boundingBox; 99} 100 101int StructurePiece::getGenDepth() 102{ 103 return genDepth; 104} 105 106bool StructurePiece::isInChunk( ChunkPos* pos ) 107{ 108 int cx = ( pos->x << 4 ); 109 int cz = ( pos->z << 4 ); 110 111 return boundingBox->intersects( cx, cz, cx + 15, cz + 15 ); 112} 113 114StructurePiece* StructurePiece::findCollisionPiece( list< StructurePiece* > *pieces, BoundingBox* box ) 115{ 116 for ( AUTO_VAR(it, pieces->begin()); it != pieces->end(); it++ ) 117 { 118 StructurePiece* piece = *it; 119 if ( piece->getBoundingBox() != NULL && piece->getBoundingBox()->intersects( box ) ) 120 { 121 return piece; 122 } 123 } 124 return NULL; 125} 126 127// 4J-PB - Added from 1.2.3 128TilePos *StructurePiece::getLocatorPosition() 129{ 130 return new TilePos(boundingBox->getXCenter(), boundingBox->getYCenter(), boundingBox->getZCenter()); 131} 132 133bool StructurePiece::edgesLiquid( Level* level, BoundingBox* chunkBB ) 134{ 135 int x0 = Math::_max( boundingBox->x0 - 1, chunkBB->x0 ); 136 int y0 = Math::_max( boundingBox->y0 - 1, chunkBB->y0 ); 137 int z0 = Math::_max( boundingBox->z0 - 1, chunkBB->z0 ); 138 int x1 = Math::_min( boundingBox->x1 + 1, chunkBB->x1 ); 139 int y1 = Math::_min( boundingBox->y1 + 1, chunkBB->y1 ); 140 int z1 = Math::_min( boundingBox->z1 + 1, chunkBB->z1 ); 141 142 // roof and floor 143 for ( int x = x0; x <= x1; x++ ) 144 { 145 for ( int z = z0; z <= z1; z++ ) 146 { 147 int tile = level->getTile( x, y0, z ); 148 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 149 { 150 return true; 151 } 152 tile = level->getTile( x, y1, z ); 153 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 154 { 155 return true; 156 } 157 } 158 } 159 // north and south 160 for ( int x = x0; x <= x1; x++ ) 161 { 162 for ( int y = y0; y <= y1; y++ ) 163 { 164 int tile = level->getTile( x, y, z0 ); 165 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 166 { 167 return true; 168 } 169 tile = level->getTile( x, y, z1 ); 170 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 171 { 172 return true; 173 } 174 } 175 } 176 // east and west 177 for ( int z = z0; z <= z1; z++ ) 178 { 179 for ( int y = y0; y <= y1; y++ ) 180 { 181 int tile = level->getTile( x0, y, z ); 182 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 183 { 184 return true; 185 } 186 tile = level->getTile( x1, y, z ); 187 if ( tile > 0 && Tile::tiles[tile]->material->isLiquid() ) 188 { 189 return true; 190 } 191 } 192 } 193 return false; 194 195} 196 197int StructurePiece::getWorldX( int x, int z ) 198{ 199 switch ( orientation ) 200 { 201 case Direction::NORTH: 202 case Direction::SOUTH: 203 return boundingBox->x0 + x; 204 case Direction::WEST: 205 return boundingBox->x1 - z; 206 case Direction::EAST: 207 return boundingBox->x0 + z; 208 default: 209 return x; 210 } 211} 212 213int StructurePiece::getWorldY( int y ) 214{ 215 if ( orientation == Direction::UNDEFINED ) 216 { 217 return y; 218 } 219 return y + boundingBox->y0; 220} 221 222int StructurePiece::getWorldZ( int x, int z ) 223{ 224 switch ( orientation ) 225 { 226 case Direction::NORTH: 227 return boundingBox->z1 - z; 228 case Direction::SOUTH: 229 return boundingBox->z0 + z; 230 case Direction::WEST: 231 case Direction::EAST: 232 return boundingBox->z0 + x; 233 default: 234 return z; 235 } 236} 237 238int StructurePiece::getOrientationData( int tile, int data ) 239{ 240 if ( tile == Tile::rail->id ) 241 { 242 if ( orientation == Direction::WEST || orientation == Direction::EAST ) 243 { 244 if ( data == BaseRailTile::DIR_FLAT_X ) 245 { 246 return BaseRailTile::DIR_FLAT_Z; 247 } 248 else 249 { 250 return BaseRailTile::DIR_FLAT_X; 251 } 252 } 253 } 254 else if ( tile == Tile::door_wood_Id || tile == Tile::door_iron_Id ) 255 { 256 if ( orientation == Direction::SOUTH ) 257 { 258 if ( data == 0 ) 259 { 260 return 2; 261 } 262 if ( data == 2 ) 263 { 264 return 0; 265 } 266 } 267 else if ( orientation == Direction::WEST ) 268 { 269 // 0 = 1 270 // 1 = 2 271 // 2 = 3 272 // 3 = 0 273 return ( data + 1 ) & 3; 274 } 275 else if ( orientation == Direction::EAST ) 276 { 277 // 0 = 3 278 // 1 = 0 279 // 2 = 1 280 // 3 = 2 281 return ( data + 3 ) & 3; 282 } 283 } 284 else if ( tile == Tile::stairs_stone_Id || tile == Tile::stairs_wood_Id || tile == Tile::stairs_netherBricks_Id || tile == Tile::stairs_stoneBrick_Id || tile == Tile::stairs_sandstone_Id) 285 { 286 if ( orientation == Direction::SOUTH ) 287 { 288 if ( data == 2 ) 289 { 290 return 3; 291 } 292 if ( data == 3 ) 293 { 294 return 2; 295 } 296 } 297 else if ( orientation == Direction::WEST ) 298 { 299 if ( data == 0 ) 300 { 301 return 2; 302 } 303 if ( data == 1 ) 304 { 305 return 3; 306 } 307 if ( data == 2 ) 308 { 309 return 0; 310 } 311 if ( data == 3 ) 312 { 313 return 1; 314 } 315 } 316 else if ( orientation == Direction::EAST ) 317 { 318 if ( data == 0 ) 319 { 320 return 2; 321 } 322 if ( data == 1 ) 323 { 324 return 3; 325 } 326 if ( data == 2 ) 327 { 328 return 1; 329 } 330 if ( data == 3 ) 331 { 332 return 0; 333 } 334 } 335 } 336 else if ( tile == Tile::ladder->id ) 337 { 338 if ( orientation == Direction::SOUTH ) 339 { 340 if ( data == Facing::NORTH ) 341 { 342 return Facing::SOUTH; 343 } 344 if ( data == Facing::SOUTH ) 345 { 346 return Facing::NORTH; 347 } 348 } 349 else if ( orientation == Direction::WEST ) 350 { 351 if ( data == Facing::NORTH ) 352 { 353 return Facing::WEST; 354 } 355 if ( data == Facing::SOUTH ) 356 { 357 return Facing::EAST; 358 } 359 if ( data == Facing::WEST ) 360 { 361 return Facing::NORTH; 362 } 363 if ( data == Facing::EAST ) 364 { 365 return Facing::SOUTH; 366 } 367 } 368 else if ( orientation == Direction::EAST ) 369 { 370 if ( data == Facing::NORTH ) 371 { 372 return Facing::EAST; 373 } 374 if ( data == Facing::SOUTH ) 375 { 376 return Facing::WEST; 377 } 378 if ( data == Facing::WEST ) 379 { 380 return Facing::NORTH; 381 } 382 if ( data == Facing::EAST ) 383 { 384 return Facing::SOUTH; 385 } 386 } 387 388 } 389 else if ( tile == Tile::button->id ) 390 { 391 if ( orientation == Direction::SOUTH ) 392 { 393 if ( data == 3 ) 394 { 395 return 4; 396 } 397 if ( data == 4 ) 398 { 399 return 3; 400 } 401 } 402 else if ( orientation == Direction::WEST ) 403 { 404 if ( data == 3 ) 405 { 406 return 1; 407 } 408 if ( data == 4 ) 409 { 410 return 2; 411 } 412 if ( data == 2 ) 413 { 414 return 3; 415 } 416 if ( data == 1 ) 417 { 418 return 4; 419 } 420 } 421 else if ( orientation == Direction::EAST ) 422 { 423 if ( data == 3 ) 424 { 425 return 2; 426 } 427 if ( data == 4 ) 428 { 429 return 1; 430 } 431 if ( data == 2 ) 432 { 433 return 3; 434 } 435 if ( data == 1 ) 436 { 437 return 4; 438 } 439 } 440 } 441 else if (tile == Tile::tripWireSource_Id || (Tile::tiles[tile] != NULL && dynamic_cast<DirectionalTile *>(Tile::tiles[tile]))) 442 { 443 if (orientation == Direction::SOUTH) 444 { 445 if (data == Direction::SOUTH || data == Direction::NORTH) 446 { 447 return Direction::DIRECTION_OPPOSITE[data]; 448 } 449 } 450 else if (orientation == Direction::WEST) 451 { 452 if (data == Direction::NORTH) 453 { 454 return Direction::WEST; 455 } 456 if (data == Direction::SOUTH) 457 { 458 return Direction::EAST; 459 } 460 if (data == Direction::WEST) 461 { 462 return Direction::NORTH; 463 } 464 if (data == Direction::EAST) 465 { 466 return Direction::SOUTH; 467 } 468 } 469 else if (orientation == Direction::EAST) 470 { 471 if (data == Direction::NORTH) 472 { 473 return Direction::EAST; 474 } 475 if (data == Direction::SOUTH) 476 { 477 return Direction::WEST; 478 } 479 if (data == Direction::WEST) 480 { 481 return Direction::NORTH; 482 } 483 if (data == Direction::EAST) 484 { 485 return Direction::SOUTH; 486 } 487 } 488 } 489 else if (tile == Tile::pistonBase_Id || tile == Tile::pistonStickyBase_Id || tile == Tile::lever_Id || tile == Tile::dispenser_Id) 490 { 491 if (orientation == Direction::SOUTH) 492 { 493 if (data == Facing::NORTH || data == Facing::SOUTH) 494 { 495 return Facing::OPPOSITE_FACING[data]; 496 } 497 } 498 else if (orientation == Direction::WEST) 499 { 500 if (data == Facing::NORTH) 501 { 502 return Facing::WEST; 503 } 504 if (data == Facing::SOUTH) 505 { 506 return Facing::EAST; 507 } 508 if (data == Facing::WEST) 509 { 510 return Facing::NORTH; 511 } 512 if (data == Facing::EAST) 513 { 514 return Facing::SOUTH; 515 } 516 } else if (orientation == Direction::EAST) 517 { 518 if (data == Facing::NORTH) 519 { 520 return Facing::EAST; 521 } 522 if (data == Facing::SOUTH) 523 { 524 return Facing::WEST; 525 } 526 if (data == Facing::WEST) 527 { 528 return Facing::NORTH; 529 } 530 if (data == Facing::EAST) 531 { 532 return Facing::SOUTH; 533 } 534 } 535 } 536 return data; 537 538} 539 540void StructurePiece::placeBlock( Level* level, int block, int data, int x, int y, int z, BoundingBox* chunkBB ) 541{ 542 int worldX = getWorldX( x, z ); 543 int worldY = getWorldY( y ); 544 int worldZ = getWorldZ( x, z ); 545 546 if ( !chunkBB->isInside( worldX, worldY, worldZ ) ) 547 { 548 return; 549 } 550 551 // 4J Stu - We shouldn't be removing bedrock when generating things (eg in SuperFlat) 552 if(worldY == 0) return; 553 554 level->setTileAndData( worldX, worldY, worldZ, block, data, Tile::UPDATE_CLIENTS); 555} 556 557 558/** 559* The purpose of this method is to wrap the getTile call on Level, in order 560* to prevent the level from generating chunks that shouldn't be loaded yet. 561* Returns 0 if the call is out of bounds. 562* 563* @param level 564* @param x 565* @param y 566* @param z 567* @param chunkPosition 568* @return 569*/ 570int StructurePiece::getBlock( Level* level, int x, int y, int z, BoundingBox* chunkBB ) 571{ 572 int worldX = getWorldX( x, z ); 573 int worldY = getWorldY( y ); 574 int worldZ = getWorldZ( x, z ); 575 576 if ( !chunkBB->isInside( worldX, worldY, worldZ ) ) 577 { 578 return 0; 579 } 580 581 return level->getTile( worldX, worldY, worldZ ); 582} 583 584void StructurePiece::generateAirBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1) 585{ 586 for (int y = y0; y <= y1; y++) 587 { 588 for (int x = x0; x <= x1; x++) 589 { 590 for (int z = z0; z <= z1; z++) 591 { 592 placeBlock(level, 0, 0, x, y, z, chunkBB); 593 } 594 } 595 } 596} 597 598void StructurePiece::generateBox( Level* level, BoundingBox* chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, 599 int edgeTile, int fillTile, bool skipAir ) 600{ 601 for ( int y = y0; y <= y1; y++ ) 602 { 603 for ( int x = x0; x <= x1; x++ ) 604 { 605 for ( int z = z0; z <= z1; z++ ) 606 { 607 608 if ( skipAir && getBlock( level, x, y, z, chunkBB ) == 0 ) 609 { 610 continue; 611 } 612 if ( y == y0 || y == y1 || x == x0 || x == x1 || z == z0 || z == z1 ) 613 { 614 placeBlock( level, edgeTile, 0, x, y, z, chunkBB ); 615 } 616 else 617 { 618 placeBlock( level, fillTile, 0, x, y, z, chunkBB ); 619 } 620 621 } 622 } 623 } 624} 625 626void StructurePiece::generateBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, int edgeTile, int edgeData, int fillTile, int fillData, bool skipAir) 627{ 628 for (int y = y0; y <= y1; y++) 629 { 630 for (int x = x0; x <= x1; x++) 631 { 632 for (int z = z0; z <= z1; z++) 633 { 634 635 if (skipAir && getBlock(level, x, y, z, chunkBB) == 0) 636 { 637 continue; 638 } 639 if (y == y0 || y == y1 || x == x0 || x == x1 || z == z0 || z == z1) 640 { 641 placeBlock(level, edgeTile, edgeData, x, y, z, chunkBB); 642 } 643 else 644 { 645 placeBlock(level, fillTile, fillData, x, y, z, chunkBB); 646 } 647 648 } 649 } 650 } 651} 652 653void StructurePiece::generateBox( Level* level, BoundingBox* chunkBB, BoundingBox* boxBB, int edgeTile, int fillTile, 654 bool skipAir ) 655{ 656 generateBox( level, chunkBB, boxBB->x0, boxBB->y0, boxBB->z0, boxBB->x1, boxBB->y1, boxBB->z1, edgeTile, fillTile, 657 skipAir ); 658} 659 660void StructurePiece::generateBox( Level* level, BoundingBox* chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, 661 bool skipAir, Random* random, StructurePiece::BlockSelector* selector ) 662{ 663 for ( int y = y0; y <= y1; y++ ) 664 { 665 for ( int x = x0; x <= x1; x++ ) 666 { 667 for ( int z = z0; z <= z1; z++ ) 668 { 669 670 if ( skipAir && getBlock( level, x, y, z, chunkBB ) == 0 ) 671 { 672 continue; 673 } 674 selector->next( random, x, y, z, y == y0 || y == y1 || x == x0 || x == x1 || z == z0 || z == z1 ); 675 placeBlock( level, selector->getNextId(), selector->getNextData(), x, y, z, chunkBB ); 676 677 } 678 } 679 } 680} 681 682void StructurePiece::generateBox( Level* level, BoundingBox* chunkBB, BoundingBox* boxBB, bool skipAir, Random* random, 683 StructurePiece::BlockSelector* selector ) 684{ 685 generateBox( level, chunkBB, boxBB->x0, boxBB->y0, boxBB->z0, boxBB->x1, boxBB->y1, boxBB->z1, skipAir, random, 686 selector ); 687} 688 689void StructurePiece::generateMaybeBox( Level* level, BoundingBox* chunkBB, Random *random, float probability, int x0, 690 int y0, int z0, int x1, int y1, int z1, int edgeTile, int fillTile, 691 bool skipAir ) 692{ 693 for ( int y = y0; y <= y1; y++ ) 694 { 695 for ( int x = x0; x <= x1; x++ ) 696 { 697 for ( int z = z0; z <= z1; z++ ) 698 { 699 700 if ( random->nextFloat() > probability ) 701 { 702 continue; 703 } 704 if ( skipAir && getBlock( level, x, y, z, chunkBB ) == 0 ) 705 { 706 continue; 707 } 708 if ( y == y0 || y == y1 || x == x0 || x == x1 || z == z0 || z == z1 ) 709 { 710 placeBlock( level, edgeTile, 0, x, y, z, chunkBB ); 711 } 712 else 713 { 714 placeBlock( level, fillTile, 0, x, y, z, chunkBB ); 715 } 716 717 } 718 } 719 } 720} 721 722void StructurePiece::maybeGenerateBlock( Level* level, BoundingBox* chunkBB, Random *random, float probability, int x, 723 int y, int z, int tile, int data ) 724{ 725 if ( random->nextFloat() < probability ) 726 { 727 placeBlock( level, tile, data, x, y, z, chunkBB ); 728 } 729} 730 731void StructurePiece::generateUpperHalfSphere( Level* level, BoundingBox* chunkBB, int x0, int y0, int z0, int x1, 732 int y1, int z1, int fillTile, bool skipAir ) 733{ 734 float diagX = (float)( x1 - x0 + 1 ); 735 float diagY = (float)( y1 - y0 + 1 ); 736 float diagZ = (float)( z1 - z0 + 1 ); 737 float cx = x0 + diagX / 2; 738 float cz = z0 + diagZ / 2; 739 740 for ( int y = y0; y <= y1; y++ ) 741 { 742 float normalizedYDistance = ( float )( y - y0 ) / diagY; 743 744 for ( int x = x0; x <= x1; x++ ) 745 { 746 float normalizedXDistance = ( float )( x - cx ) / ( diagX * 0.5f ); 747 748 for ( int z = z0; z <= z1; z++ ) 749 { 750 float normalizedZDistance = ( float )( z - cz ) / ( diagZ * 0.5f ); 751 752 if ( skipAir && getBlock( level, x, y, z, chunkBB ) == 0 ) 753 { 754 continue; 755 } 756 757 float dist = ( normalizedXDistance * normalizedXDistance ) + ( normalizedYDistance * 758 normalizedYDistance ) + ( normalizedZDistance * normalizedZDistance ); 759 760 if ( dist <= 1.05f ) 761 { 762 placeBlock( level, fillTile, 0, x, y, z, chunkBB ); 763 } 764 765 } 766 } 767 } 768 769} 770 771void StructurePiece::generateAirColumnUp( Level* level, int x, int startY, int z, BoundingBox* chunkBB ) 772{ 773 int worldX = getWorldX( x, z ); 774 int worldY = getWorldY( startY ); 775 int worldZ = getWorldZ( x, z ); 776 777 if ( !chunkBB->isInside( worldX, worldY, worldZ ) ) 778 { 779 return; 780 } 781 782 while ( !level->isEmptyTile( worldX, worldY, worldZ ) && worldY < Level::maxBuildHeight - 1 ) 783 { 784 level->setTileAndData( worldX, worldY, worldZ, 0, 0, Tile::UPDATE_CLIENTS); 785 worldY++; 786 } 787} 788 789void StructurePiece::fillColumnDown( Level* level, int tile, int tileData, int x, int startY, int z, BoundingBox* chunkBB ) 790{ 791 int worldX = getWorldX( x, z ); 792 int worldY = getWorldY( startY ); 793 int worldZ = getWorldZ( x, z ); 794 795 if ( !chunkBB->isInside( worldX, worldY, worldZ ) ) 796 { 797 return; 798 } 799 800 while ( ( level->isEmptyTile( worldX, worldY, worldZ ) || level->getMaterial( worldX, worldY, worldZ )->isLiquid() ) && worldY > 1 ) 801 { 802 level->setTileAndData( worldX, worldY, worldZ, tile, tileData, Tile::UPDATE_CLIENTS ); 803 worldY--; 804 } 805} 806 807bool StructurePiece::createChest( Level* level, BoundingBox* chunkBB, Random* random, int x, int y, int z, 808 WeighedTreasureArray treasure, int numRolls ) 809{ 810 int worldX = getWorldX( x, z ); 811 int worldY = getWorldY( y ); 812 int worldZ = getWorldZ( x, z ); 813 814 if ( chunkBB->isInside( worldX, worldY, worldZ ) ) 815 { 816 if ( level->getTile( worldX, worldY, worldZ ) != Tile::chest->id ) 817 { 818 level->setTileAndData( worldX, worldY, worldZ, Tile::chest->id, 0, Tile::UPDATE_CLIENTS ); 819 shared_ptr<ChestTileEntity> chest = dynamic_pointer_cast<ChestTileEntity>(level->getTileEntity( worldX, worldY, worldZ )); 820 if ( chest != NULL ) WeighedTreasure::addChestItems( random, treasure, chest, numRolls ); 821 return true; 822 } 823 } 824 return false; 825} 826 827bool StructurePiece::createDispenser(Level *level, BoundingBox *chunkBB, Random *random, int x, int y, int z, int facing, WeighedTreasureArray items, int numRolls) 828{ 829 int worldX = getWorldX(x, z); 830 int worldY = getWorldY(y); 831 int worldZ = getWorldZ(x, z); 832 833 if (chunkBB->isInside(worldX, worldY, worldZ)) 834 { 835 if (level->getTile(worldX, worldY, worldZ) != Tile::dispenser_Id) 836 { 837 level->setTileAndData(worldX, worldY, worldZ, Tile::dispenser_Id, getOrientationData(Tile::dispenser_Id, facing), Tile::UPDATE_CLIENTS); 838 shared_ptr<DispenserTileEntity> dispenser = dynamic_pointer_cast<DispenserTileEntity>(level->getTileEntity(worldX, worldY, worldZ)); 839 if (dispenser != NULL) WeighedTreasure::addDispenserItems(random, items, dispenser, numRolls); 840 return true; 841 } 842 } 843 return false; 844} 845 846void StructurePiece::createDoor( Level* level, BoundingBox* chunkBB, Random* random, int x, int y, int z, 847 int orientation ) 848{ 849 int worldX = getWorldX( x, z ); 850 int worldY = getWorldY( y ); 851 int worldZ = getWorldZ( x, z ); 852 853 if ( chunkBB->isInside( worldX, worldY, worldZ ) ) 854 { 855 DoorItem::place( level, worldX, worldY, worldZ, orientation, Tile::door_wood ); 856 } 857}