the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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}