#pragma once #include "Common.h" #include "util/ByteUtil.h" #include #include namespace Feather { struct MinecraftUUID { std::array data; }; inline MinecraftUUID ReverseBytes(MinecraftUUID uuid) { return MinecraftUUID { .data = { ReverseBytes(uuid.data[0]), ReverseBytes(uuid.data[1]) } }; } enum class Direction : uint8 { DOWN, // -Y UP, // +Y NORTH, // -Z SOUTH, // +Z WEST, // -X EAST // +X }; struct BlockPos { int32_t x, y, z; BlockPos(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z) {} // Decodes from packed long BlockPos(int64_t l) : x(l << (64 - X_OFFSET - PACKED_X_LENGTH) >> (64 - PACKED_X_LENGTH)) , y(l << (64 - Y_OFFSET - PACKED_Y_LENGTH) >> (64 - PACKED_Y_LENGTH)) , z(l << (64 - Z_OFFSET - PACKED_Z_LENGTH) >> (64 - PACKED_Z_LENGTH)) {} BlockPos() : BlockPos(0, 0, 0) {} inline int64_t Encode() { int64_t l = 0; l |= ((long)x & PACKED_X_MASK) << X_OFFSET; l |= ((long)y & PACKED_Y_MASK) << Y_OFFSET; l |= ((long)z & PACKED_Z_MASK) << Z_OFFSET; return l; } private: // X: 26 bits, Z: 26 bits, Y: 12 bits static const int PACKED_X_LENGTH = 1 + Math::CeilLog2(Math::RoundToPowerOf2(30000000)); // should be 26 static const int PACKED_Z_LENGTH = PACKED_X_LENGTH; // same as X static const int PACKED_Y_LENGTH = 64 - PACKED_X_LENGTH - PACKED_Z_LENGTH; // should be 12 static const int64_t PACKED_X_MASK = (1 << PACKED_X_LENGTH) - 1; static const int64_t PACKED_Y_MASK = (1 << PACKED_Y_LENGTH) - 1; static const int64_t PACKED_Z_MASK = (1 << PACKED_Z_LENGTH) - 1; // order is X Z Y static const int Y_OFFSET = 0; static const int Z_OFFSET = PACKED_Y_LENGTH; static const int X_OFFSET = PACKED_Y_LENGTH + PACKED_Z_LENGTH; }; struct ChunkPos { int32_t x, z; ChunkPos(int32_t x, int32_t z) : x(x), z(z) {} // Coordinate of the 16x16 chunk containing this block ChunkPos(BlockPos pos) : x(pos.x >> 4), z(pos.z >> 4) {} // Decode from packed int64 ChunkPos(int64_t packed) : x((int32_t)packed), z(packed >> 32) {} // Pack into one int64 inline int64_t Encode() { return ((int64_t)x & 0xFFFFFFFF) | (((int64_t)z & 0xFFFFFFFF) << 32); } bool operator==(const ChunkPos& o) const { return x == o.x && z == o.z; } bool operator<(const ChunkPos& o) const { return x < o.x || (x == o.x && z < o.z); } }; // Which 32x32 chunk region file (r...mca) the chunk is stored in struct RegionPos { const int32_t x, z; RegionPos(ChunkPos pos) : x(pos.x >> 5), z(pos.z >> 5) {} }; // Position of chunk relative to its region struct RegionLocalPos { const int32_t x, z; RegionLocalPos(ChunkPos pos) : x(pos.x & 0x1F), z(pos.z & 0x1F) {} }; }