1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#pragma once
#include "WeighedRandom.h"
#include "BoundingBox.h"
#include "StructureFeatureIO.h"
class Level;
class Random;
class ChunkPos;
class BlockSelector;
class ChestTileEntity;
class TilePos;
/**
*
* A structure piece is a construction or room, located somewhere in the world
* with a given orientatino (out of Direction.java). Structure pieces have a
* bounding box that says where the piece is located and its bounds, and the
* orientation is used to translate local coordinates into world coordinates.
* <p>
* The default orientation is Direction.UNDEFINED, in which case no translation
* will occur. If the orientation is Direction.NORTH, coordinate (0, 0, 0) will
* be at (boundingBox.x0, boundingBox.y0, boundingBox.z1). In other words, (1,
* 1, 1) will be translated to (boundingBox.x0 + 1, boundingBox.y0 + 1,
* boundingBox.z1 - 1).
* <p>
* When using Direction.SOUTH, the x coordinate will be the same, and the z
* coordinate will be flipped. In other words, the bounding box is NOT rotated!
* It is only flipped along the z axis. Also note that the bounding box is in
* world coordinates, so the local drawing must never reach outside of this.
* <p>
* When using east and west coordinates, the local z coordinate will be swapped
* with the local x coordinate. For example, (0, 0, 0) is (boundingBox.z1,
* boundingBox.y0, boundingBox.z0), and (1, 1, 1) becomes (boundingBox.x1 - 1,
* boundingBox.y0 + 1, boundingBox.z0 + 1) when using Direction.WEST.
* <p>
* When-ever a structure piece is placing blocks, it is VERY IMPORTANT to always
* make sure that all getTile and setTile calls are within the chunk's bounding
* box. Failing to check this will cause the level generator to create new
* chunks, leading to infinite loops and other errors.
*/
class StructurePiece
{
public:
virtual EStructurePiece GetType() = 0;
public:
class BlockSelector
{
protected:
int nextId;
int nextData;
public:
virtual void next(Random *random, int worldX, int worldY, int worldZ, bool isEdge) {}
virtual int getNextId() { return nextId; }
virtual int getNextData() { return nextData; }
};
public: // 4J is protected in java, but accessed from VillagePieces, not sure how
BoundingBox *boundingBox;
protected:
int orientation;
int genDepth;
public:
StructurePiece();
protected:
StructurePiece(int genDepth);
public:
virtual ~StructurePiece();
virtual CompoundTag *createTag();
protected:
virtual void addAdditonalSaveData(CompoundTag *tag) = 0;
public:
virtual void load(Level *level, CompoundTag *tag);
protected:
virtual void readAdditonalSaveData(CompoundTag *tag) = 0;
public:
virtual void addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random);
virtual bool postProcess(Level *level, Random *random, BoundingBox *chunkBB) = 0;
virtual BoundingBox *getBoundingBox();
int getGenDepth();
public:
bool isInChunk(ChunkPos *pos);
static StructurePiece *findCollisionPiece(list<StructurePiece *> *pieces, BoundingBox *box);
virtual TilePos *getLocatorPosition();
protected:
bool edgesLiquid(Level *level, BoundingBox *chunkBB);
public:
// 4J Stu - Made these public to use in game rules
int getWorldX(int x, int z);
int getWorldY(int y);
int getWorldZ(int x, int z);
int getOrientationData(int tile, int data);
virtual void placeBlock(Level *level, int block, int data, int x, int y, int z, BoundingBox *chunkBB);
/**
* The purpose of this method is to wrap the getTile call on Level, in order
* to prevent the level from generating chunks that shouldn't be loaded yet.
* Returns 0 if the call is out of bounds.
*
* @param level
* @param x
* @param y
* @param z
* @param chunkPosition
* @return
*/
virtual int getBlock(Level *level, int x, int y, int z, BoundingBox *chunkBB);
virtual void generateAirBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1);
virtual void generateBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, int edgeTile, int fillTile, bool skipAir);
virtual void 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);
virtual void generateBox(Level *level, BoundingBox *chunkBB, BoundingBox *boxBB, int edgeTile, int fillTile, bool skipAir);
virtual void generateBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, bool skipAir, Random *random, BlockSelector *selector);
virtual void generateBox(Level *level, BoundingBox *chunkBB, BoundingBox *boxBB, bool skipAir, Random *random, BlockSelector *selector);
virtual void generateMaybeBox(Level *level, BoundingBox *chunkBB, Random *random, float probability, int x0, int y0, int z0, int x1, int y1, int z1, int edgeTile, int fillTile, bool skipAir);
virtual void maybeGenerateBlock(Level *level, BoundingBox *chunkBB, Random *random, float probability, int x, int y, int z, int tile, int data);
virtual void generateUpperHalfSphere(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, int fillTile, bool skipAir);
virtual void generateAirColumnUp(Level *level, int x, int startY, int z, BoundingBox *chunkBB);
virtual void fillColumnDown(Level *level, int tile, int tileData, int x, int startY, int z, BoundingBox *chunkBB);
virtual bool createChest(Level *level, BoundingBox *chunkBB, Random *random, int x, int y, int z, WeighedTreasureArray treasure, int numRolls);
virtual bool createDispenser(Level *level, BoundingBox *chunkBB, Random *random, int x, int y, int z, int facing, WeighedTreasureArray items, int numRolls);
protected:
void createDoor(Level *level, BoundingBox *chunkBB, Random *random, int x, int y, int z, int orientation);
};
|