From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- Minecraft.World/StructurePiece.h | 117 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 Minecraft.World/StructurePiece.h (limited to 'Minecraft.World/StructurePiece.h') diff --git a/Minecraft.World/StructurePiece.h b/Minecraft.World/StructurePiece.h new file mode 100644 index 00000000..f1ead433 --- /dev/null +++ b/Minecraft.World/StructurePiece.h @@ -0,0 +1,117 @@ +#pragma once +#include "WeighedRandom.h" +#include "BoundingBox.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. + *

+ * 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). + *

+ * 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. + *

+ * 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. + *

+ * 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: + 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; + + StructurePiece(int genDepth); +public: + virtual ~StructurePiece(); + + virtual void addChildren(StructurePiece *startPiece, list *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 *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); +}; -- cgit v1.2.3