From 6c67d4a4c7b3fef238fab6af15528a4ae9bcdcec Mon Sep 17 00:00:00 2001 From: darcy Date: Thu, 31 Oct 2024 11:33:29 +1100 Subject: [PATCH 01/19] Create `Coordinate2D` type --- include/mcpp/util.h | 108 ++++++++++++++++++++++++++++++++++++++++++++ src/util.cpp | 36 +++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index e503b43..e738d8c 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -11,6 +11,9 @@ * */ namespace mcpp { + +struct Coordinate2D; + /** * Represented using integers since sub-unit coordinates are not of particular * relevance. Allows for operations such as addition between coordinates. @@ -34,6 +37,15 @@ struct Coordinate { */ Coordinate(double x, double y, double z); + /** + * @brief Constructs a Coordinate object from a Coordinate2D object and a + * y value. + * + * @param coord The Coordinate2D object. + * @param y The y value. + */ + constexpr Coordinate(const Coordinate2D& coord, int y); + /** * @brief Adds two Coordinate objects. * @@ -89,6 +101,102 @@ struct Coordinate { int z; }; +/** + * @brief Height-agnostic coordinate class. + * + * Represented using integers since sub-unit coordinates are not of particular + * relevance. Allows for operations such as addition between flat coordinates. + */ +struct Coordinate2D { + /** + * @brief Constructs a Coordinate2D object with integer values. + * + * @param x The x-coordinate. + * @param z The z-coordinate. + */ + constexpr Coordinate2D(int x, int z) : x(x), z(z) {} + + /** + * @brief Constructs a Coordinate2D object with zero values. + */ + constexpr Coordinate2D() : x(0), z(0) {} + + /** + * @brief Constructs a Coordinate2D object with double values. + * + * @param x The x-coordinate as a double. + * @param z The z-coordinate as a double. + */ + constexpr Coordinate2D(double x, double z) + : x(static_cast(x)), z(static_cast(z)) {} + + /** + * @brief Constructs a Coordinate2D object from a Coordinate object. + * + * @param coord The Coordinate object. + */ + constexpr Coordinate2D(const Coordinate& coord) : x(coord.x), z(coord.z) {} + + /** + * @brief Adds two Coordinate2D objects. + * + * @param obj The Coordinate2D object to add. + * @return A new Coordinate2D object representing the sum of the two + * coordinates. + */ + Coordinate2D operator+(const Coordinate2D& obj) const; + + // TODO: Add Coordinate + Coordinate2D + + /** + * @brief Checks if two Coordinate2D objects are equal. + * + * @param obj The Coordinate2D object to compare with. + * @return True if the flat coordinates are equal, false otherwise. + */ + bool operator==(const Coordinate2D& obj) const; + + /** + * @brief Checks if two Coordinate2D objects are not equal. + * + * @param obj The Coordinate2D object to compare with. + * @return True if the flat coordinates are not equal, false otherwise. + */ + bool operator!=(const Coordinate2D& obj) const; + + /** + * @brief Subtracts one Coordinate2D object from another. + * + * @param obj The Coordinate2D object to subtract. + * @return A new Coordinate2D object representing the difference between + * the two coordinates. + */ + Coordinate2D operator-(const Coordinate2D& obj) const; + + /** + * @brief Creates a copy of the Coordinate2D object. + * + * @return A new Coordinate2D object that is a copy of the current object. + */ + [[nodiscard]] Coordinate2D clone() const; + + /** + * @brief Outputs the Coordinate2D object to an ostream. + * + * @param out The output stream. + * @param coord The Coordinate2D object to output. + * @return The output stream with the Coordinate object's values. + */ + friend std::ostream& operator<<(std::ostream& out, + const Coordinate2D& coord); + + int x; + int z; +}; + +constexpr Coordinate::Coordinate(const Coordinate2D& coord, int y) + : x(coord.x), y(y), z(coord.z) {} + /** * Stores a 3D cuboid of BlockTypes while preserving their relative location to * the base point they were gathered at and each other. diff --git a/src/util.cpp b/src/util.cpp index f52aa55..9c47d88 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -56,6 +56,42 @@ std::ostream& operator<<(std::ostream& out, const Coordinate& coord) { return out; } +Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const { + Coordinate2D result; + result.x = this->x + obj.x; + result.z = this->z + obj.z; + return result; +} + +bool Coordinate2D::operator==(const Coordinate2D& obj) const { + return (this->x == obj.x) && (this->z == obj.z); +} + +bool Coordinate2D::operator!=(const Coordinate2D& obj) const { + return !(*this == obj); +} + +Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { + Coordinate2D result; + result.x = this->x - obj.x; + result.z = this->z - obj.z; + return result; +} + +Coordinate2D Coordinate2D::clone() const { + return Coordinate2D(this->x, this->z); +} + +std::string to_string(const Coordinate2D& coord) { + using std::to_string; + return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; +} + +std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord) { + out << to_string(coord); + return out; +} + Chunk::Chunk(const Coordinate& loc1, const Coordinate& loc2, const std::vector& block_list) { Coordinate min{std::min(loc1.x, loc2.x), std::min(loc1.y, loc2.y), From ce1c51d0855f1d92cc8ac049ca32bedfe5bf6e47 Mon Sep 17 00:00:00 2001 From: darcy Date: Thu, 31 Oct 2024 12:59:17 +1100 Subject: [PATCH 02/19] Use `Coordinate2D` for height-related functions --- include/mcpp/mcpp.h | 16 ++++++++-------- include/mcpp/util.h | 14 +++++++------- src/mcpp.cpp | 9 +++++---- src/util.cpp | 6 +++--- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/mcpp/mcpp.h b/include/mcpp/mcpp.h index a6ecbce..bb3e9b9 100644 --- a/include/mcpp/mcpp.h +++ b/include/mcpp/mcpp.h @@ -125,19 +125,18 @@ class MinecraftConnection { Chunk getBlocks(const Coordinate& loc1, const Coordinate& loc2); /** - * @brief Returns the height of the specific provided x and z coordinate + * @brief Returns the height of the specific provided 2D coordinate * * ***IMPORTANT:*** * DO NOT USE FOR LARGE AREAS, IT WILL BE VERY SLOW * USE getHeights() INSTEAD * - * Gets the y-value of the highest non-air block at the specified (x, z) + * Gets the y-value of the highest non-air block at the specified 2D * coordinate. - * @param x - * @param z + * @param loc 2D coordinate * @return Returns the integer y-height at the requested coordinate. */ - int getHeight(int x, int z); + int getHeight(Coordinate2D loc); /** * @brief Provides a scaled option of the getHeight call to allow for @@ -145,10 +144,11 @@ class MinecraftConnection { * * \par USE THIS instead of getHeight in a for loop. * - * @param loc1 - * @param loc2 + * @param loc1 1st corner of rectangle + * @param loc2 2nd corner of rectangle * @return Returns a vector of integers representing the 2D area of heights. */ - const HeightMap getHeights(const Coordinate& loc1, const Coordinate& loc2); + const HeightMap getHeights(const Coordinate2D& loc1, + const Coordinate2D& loc2); }; } // namespace mcpp diff --git a/include/mcpp/util.h b/include/mcpp/util.h index e738d8c..6a819ff 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -451,7 +451,7 @@ struct HeightMap { Iterator begin() { return Iterator(&raw_heights[0]); } Iterator end() { return Iterator(&raw_heights[_x_len * _z_len]); } - HeightMap(const Coordinate& loc1, const Coordinate& loc2, + HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, const std::vector& heights); ~HeightMap(); @@ -469,10 +469,10 @@ struct HeightMap { /** * Get the height at a Minecraft coordinate if saved inside the height map - * @param loc: Coordinate in Minecraft world to access in the map + * @param loc: 2D coordinate in Minecraft world to access in the map * @return: height at specified coordinate */ - int get_worldspace(const Coordinate& loc) const; + int get_worldspace(const Coordinate2D& loc) const; /** * Fill a coordinate inplace with the highest y coordinate at the `loc`'s x @@ -494,13 +494,13 @@ struct HeightMap { int z_len() const; /** - * Gets the minimum coordinate in the HeightMap. - * @return the minimum coordinate in the HeightMap. + * Gets the minimum 2D coordinate in the HeightMap. + * @return the minimum 2D coordinate in the HeightMap. */ - Coordinate base_pt() const; + Coordinate2D base_pt() const; private: - Coordinate _base_pt; + Coordinate2D _base_pt; int _x_len; int _z_len; int* raw_heights; diff --git a/src/mcpp.cpp b/src/mcpp.cpp index cacad72..4bf6cdb 100644 --- a/src/mcpp.cpp +++ b/src/mcpp.cpp @@ -112,13 +112,14 @@ Chunk MinecraftConnection::getBlocks(const Coordinate& loc1, return Chunk{loc1, loc2, result}; } -int MinecraftConnection::getHeight(int x, int z) { - std::string returnValue = conn->sendReceiveCommand("world.getHeight", x, z); +int MinecraftConnection::getHeight(Coordinate2D loc) { + std::string returnValue = + conn->sendReceiveCommand("world.getHeight", loc.x, loc.z); return stoi(returnValue); } -const HeightMap MinecraftConnection::getHeights(const Coordinate& loc1, - const Coordinate& loc2) { +const HeightMap MinecraftConnection::getHeights(const Coordinate2D& loc1, + const Coordinate2D& loc2) { std::string returnValue = conn->sendReceiveCommand( "world.getHeights", loc1.x, loc1.z, loc2.x, loc2.z); diff --git a/src/util.cpp b/src/util.cpp index 9c47d88..e1c0f75 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -156,7 +156,7 @@ int Chunk::z_len() const { return this->_z_len; } Coordinate Chunk::base_pt() const { return this->_base_pt.clone(); } -HeightMap::HeightMap(const Coordinate& loc1, const Coordinate& loc2, +HeightMap::HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, const std::vector& heights) { _base_pt = Coordinate{ std::min(loc1.x, loc2.x), @@ -203,7 +203,7 @@ int HeightMap::get(int x, int z) const { return raw_heights[x * _z_len + z]; } -int HeightMap::get_worldspace(const Coordinate& loc) const { +int HeightMap::get_worldspace(const Coordinate2D& loc) const { return get(loc.x - _base_pt.x, loc.z - _base_pt.z); } @@ -215,6 +215,6 @@ int HeightMap::x_len() const { return this->_x_len; } int HeightMap::z_len() const { return this->_z_len; } -Coordinate HeightMap::base_pt() const { return this->_base_pt.clone(); } +Coordinate2D HeightMap::base_pt() const { return this->_base_pt.clone(); } } // namespace mcpp From 06ff1ffec265278bb7a1e8af8acc45d8b1eb3eb7 Mon Sep 17 00:00:00 2001 From: darcy Date: Tue, 3 Dec 2024 15:48:31 +1100 Subject: [PATCH 03/19] Update `pyramid` example --- example/pyramid.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/pyramid.cpp b/example/pyramid.cpp index ec6dff4..c90a866 100644 --- a/example/pyramid.cpp +++ b/example/pyramid.cpp @@ -34,8 +34,7 @@ int main() { int min_height = *std::min_element(heights.begin(), heights.end()); // Build rings, diminishing up to pyramid height - mcpp::Coordinate base_pt = heights.base_pt(); - base_pt.y = min_height; + mcpp::Coordinate base_pt = {heights.base_pt(), min_height}; int side_len = pyramid_base_len; for (int i = 0; i < PYRAMID_HEIGHT; i++) { make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2)); From 1cf25fc21f172216d90abd00b2b80fb38ded3441 Mon Sep 17 00:00:00 2001 From: darcy Date: Tue, 3 Dec 2024 15:49:50 +1100 Subject: [PATCH 04/19] Update `minecraft_tests` test --- test/minecraft_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/minecraft_tests.cpp b/test/minecraft_tests.cpp index 7032c9f..1cd57ab 100644 --- a/test/minecraft_tests.cpp +++ b/test/minecraft_tests.cpp @@ -112,7 +112,7 @@ TEST_CASE("Test the main mcpp class") { SUBCASE("getHeight") { Coordinate heightTestLoc(300, 200, 300); mc.setBlock(heightTestLoc, Blocks::DIRT); - auto height = mc.getHeight(heightTestLoc.x, heightTestLoc.z); + auto height = mc.getHeight(heightTestLoc); CHECK_EQ(height, heightTestLoc.y); // Clean up From c1aeef8f58165ddd6c5ba0b4da123639f2972694 Mon Sep 17 00:00:00 2001 From: darcy Date: Wed, 15 Jan 2025 17:01:12 +1100 Subject: [PATCH 05/19] Add `MinecraftConnection::fillHeight` method --- include/mcpp/mcpp.h | 15 +++++++++++++++ src/mcpp.cpp | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/include/mcpp/mcpp.h b/include/mcpp/mcpp.h index bb3e9b9..f89d7eb 100644 --- a/include/mcpp/mcpp.h +++ b/include/mcpp/mcpp.h @@ -138,6 +138,21 @@ class MinecraftConnection { */ int getHeight(Coordinate2D loc); + /** + * @brief Returns the coordinate with the x, z, and in-world height of the + * specific provided 2D coordinate + * + * ***IMPORTANT:*** + * DO NOT USE FOR LARGE AREAS, IT WILL BE VERY SLOW + * USE getHeights() INSTEAD + * + * Gets the y-value of the highest non-air block at the specified 2D + * coordinate, and creates a new 3D coordinate. + * @param loc 2D coordinate + * @return Returns the coordinate with the filled-in height. + */ + Coordinate fillHeight(Coordinate2D loc); + /** * @brief Provides a scaled option of the getHeight call to allow for * considerable performance gains. diff --git a/src/mcpp.cpp b/src/mcpp.cpp index 4bf6cdb..1b17ea9 100644 --- a/src/mcpp.cpp +++ b/src/mcpp.cpp @@ -118,6 +118,11 @@ int MinecraftConnection::getHeight(Coordinate2D loc) { return stoi(returnValue); } +Coordinate MinecraftConnection::fillHeight(Coordinate2D loc) { + int y = this->getHeight(loc); + return Coordinate(loc.x, y, loc.z); +} + const HeightMap MinecraftConnection::getHeights(const Coordinate2D& loc1, const Coordinate2D& loc2) { std::string returnValue = conn->sendReceiveCommand( From 7a36531122497b068c633941a626a3663aff6820 Mon Sep 17 00:00:00 2001 From: darcy Date: Wed, 15 Jan 2025 17:28:19 +1100 Subject: [PATCH 06/19] Replace `Coordinate2D` to `Coordinate` constructor with explicit named method --- example/pyramid.cpp | 2 +- include/mcpp/util.h | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/example/pyramid.cpp b/example/pyramid.cpp index c90a866..50cd3b5 100644 --- a/example/pyramid.cpp +++ b/example/pyramid.cpp @@ -34,7 +34,7 @@ int main() { int min_height = *std::min_element(heights.begin(), heights.end()); // Build rings, diminishing up to pyramid height - mcpp::Coordinate base_pt = {heights.base_pt(), min_height}; + mcpp::Coordinate base_pt = heights.base_pt().withHeight(min_height); int side_len = pyramid_base_len; for (int i = 0; i < PYRAMID_HEIGHT; i++) { make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2)); diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 5779fcc..b3138da 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -44,15 +44,6 @@ struct Coordinate { : x(static_cast(x)), y(static_cast(y)), z(static_cast(z)) {} - /** - * @brief Constructs a Coordinate object from a Coordinate2D object and a - * y value. - * - * @param coord The Coordinate2D object. - * @param y The y value. - */ - constexpr Coordinate(const Coordinate2D& coord, int y); - /** * @brief Adds two Coordinate objects. * @@ -144,6 +135,15 @@ struct Coordinate2D { */ constexpr Coordinate2D(const Coordinate& coord) : x(coord.x), z(coord.z) {} + /** + * @brief Constructs a Coordinate object from a Coordinate2D object and a + * y value. + * + * @param coord The Coordinate2D object. + * @param y The y value. + */ + constexpr Coordinate withHeight(int y); + /** * @brief Adds two Coordinate2D objects. * @@ -201,8 +201,9 @@ struct Coordinate2D { int z; }; -constexpr Coordinate::Coordinate(const Coordinate2D& coord, int y) - : x(coord.x), y(y), z(coord.z) {} +constexpr Coordinate Coordinate2D::withHeight(int y) { + return Coordinate(this->x, y, this->z); +} /** * Stores a 3D cuboid of BlockTypes while preserving their relative location to From a8284af40783bc5058d797c32fd1dc23e53c2b62 Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 29 Mar 2025 17:13:21 +1100 Subject: [PATCH 07/19] fix: make `Coordinate2D::withHeight` const --- include/mcpp/util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index b3138da..51009a0 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -142,7 +142,7 @@ struct Coordinate2D { * @param coord The Coordinate2D object. * @param y The y value. */ - constexpr Coordinate withHeight(int y); + constexpr Coordinate withHeight(int y) const; /** * @brief Adds two Coordinate2D objects. @@ -201,7 +201,7 @@ struct Coordinate2D { int z; }; -constexpr Coordinate Coordinate2D::withHeight(int y) { +constexpr Coordinate Coordinate2D::withHeight(int y) const { return Coordinate(this->x, y, this->z); } From cd5a170752e3069a43606b8664fdc368d6ff5d86 Mon Sep 17 00:00:00 2001 From: darcy Date: Sun, 30 Mar 2025 12:52:50 +1100 Subject: [PATCH 08/19] lint: use snake_case --- example/pyramid.cpp | 2 +- include/mcpp/util.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example/pyramid.cpp b/example/pyramid.cpp index 50cd3b5..56ce0a7 100644 --- a/example/pyramid.cpp +++ b/example/pyramid.cpp @@ -34,7 +34,7 @@ int main() { int min_height = *std::min_element(heights.begin(), heights.end()); // Build rings, diminishing up to pyramid height - mcpp::Coordinate base_pt = heights.base_pt().withHeight(min_height); + mcpp::Coordinate base_pt = heights.base_pt().with_height(min_height); int side_len = pyramid_base_len; for (int i = 0; i < PYRAMID_HEIGHT; i++) { make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2)); diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 51009a0..0de8f08 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -142,7 +142,7 @@ struct Coordinate2D { * @param coord The Coordinate2D object. * @param y The y value. */ - constexpr Coordinate withHeight(int y) const; + constexpr Coordinate with_height(int y) const; /** * @brief Adds two Coordinate2D objects. @@ -201,7 +201,7 @@ struct Coordinate2D { int z; }; -constexpr Coordinate Coordinate2D::withHeight(int y) const { +constexpr Coordinate Coordinate2D::with_height(int y) const { return Coordinate(this->x, y, this->z); } From dd4e1f60eec554a512824ac90f6814ac933c5c83 Mon Sep 17 00:00:00 2001 From: darcy Date: Sun, 30 Mar 2025 16:41:30 +1100 Subject: [PATCH 09/19] feat: implement `Coordinate + Coordinate2D` --- include/mcpp/util.h | 4 ++-- src/util.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 0de8f08..901a688 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -53,6 +53,8 @@ struct Coordinate { */ Coordinate operator+(const Coordinate& obj) const; + Coordinate operator+(const Coordinate2D& obj) const; + /** * @brief Checks if two Coordinate objects are equal. * @@ -153,8 +155,6 @@ struct Coordinate2D { */ Coordinate2D operator+(const Coordinate2D& obj) const; - // TODO: Add Coordinate + Coordinate2D - /** * @brief Checks if two Coordinate2D objects are equal. * diff --git a/src/util.cpp b/src/util.cpp index c4d8096..ca8f516 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -13,6 +13,14 @@ Coordinate Coordinate::operator+(const Coordinate& obj) const { return result; } +Coordinate Coordinate::operator+(const Coordinate2D& obj) const { + Coordinate result; + result.x = this->x + obj.x; + result.y = this->y; + result.z = this->z + obj.z; + return result; +} + bool Coordinate::operator==(const Coordinate& obj) const { return (this->x == obj.x) && (this->y == obj.y) && (this->z == obj.z); } From cb38438dc551ef58f947fda6cb9ed0fcf8f978f2 Mon Sep 17 00:00:00 2001 From: darcy Date: Mon, 31 Mar 2025 07:50:00 +1100 Subject: [PATCH 10/19] feat: remove `Coordinate2D::clone` --- include/mcpp/util.h | 7 ------- src/util.cpp | 8 ++------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 901a688..17964d1 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -180,13 +180,6 @@ struct Coordinate2D { */ Coordinate2D operator-(const Coordinate2D& obj) const; - /** - * @brief Creates a copy of the Coordinate2D object. - * - * @return A new Coordinate2D object that is a copy of the current object. - */ - [[nodiscard]] Coordinate2D clone() const; - /** * @brief Outputs the Coordinate2D object to an ostream. * diff --git a/src/util.cpp b/src/util.cpp index ca8f516..6ad5c97 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -74,10 +74,6 @@ Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { return result; } -Coordinate2D Coordinate2D::clone() const { - return Coordinate2D(this->x, this->z); -} - std::string to_string(const Coordinate2D& coord) { using std::to_string; return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; @@ -175,7 +171,7 @@ HeightMap& HeightMap::operator=(const HeightMap& other) noexcept { delete[] raw_heights; // Copy data from the other object - _base_pt = other._base_pt.clone(); + _base_pt = other._base_pt; _x_len = other._x_len; _z_len = other._z_len; @@ -211,6 +207,6 @@ int HeightMap::x_len() const { return this->_x_len; } int HeightMap::z_len() const { return this->_z_len; } -Coordinate2D HeightMap::base_pt() const { return this->_base_pt.clone(); } +Coordinate2D HeightMap::base_pt() const { return this->_base_pt; } } // namespace mcpp From 6efeb883fdbc57b40eca092c468126cfcbc166fc Mon Sep 17 00:00:00 2001 From: darcy Date: Mon, 31 Mar 2025 07:53:25 +1100 Subject: [PATCH 11/19] feat: move `Coordinate2D::with_height` to cpp file, remove `constexpr` --- include/mcpp/util.h | 6 +----- src/util.cpp | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/mcpp/util.h b/include/mcpp/util.h index 17964d1..d13cda6 100644 --- a/include/mcpp/util.h +++ b/include/mcpp/util.h @@ -144,7 +144,7 @@ struct Coordinate2D { * @param coord The Coordinate2D object. * @param y The y value. */ - constexpr Coordinate with_height(int y) const; + Coordinate with_height(int y) const; /** * @brief Adds two Coordinate2D objects. @@ -194,10 +194,6 @@ struct Coordinate2D { int z; }; -constexpr Coordinate Coordinate2D::with_height(int y) const { - return Coordinate(this->x, y, this->z); -} - /** * Stores a 3D cuboid of BlockTypes while preserving their relative location to * the base point they were gathered at and each other. diff --git a/src/util.cpp b/src/util.cpp index 6ad5c97..7f56ec0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -52,6 +52,10 @@ std::ostream& operator<<(std::ostream& out, const Coordinate& coord) { return out; } +Coordinate Coordinate2D::with_height(int y) const { + return Coordinate(this->x, y, this->z); +} + Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const { Coordinate2D result; result.x = this->x + obj.x; From a48292c7ecd3140f8dc9693d998cecd94889f585 Mon Sep 17 00:00:00 2001 From: Artemis Rosman <73006620+rozukke@users.noreply.github.com> Date: Sat, 15 Feb 2025 16:47:56 +1100 Subject: [PATCH 12/19] fix: update clang-format for readability --- .clang-format | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index abdf0a2..861afc6 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,5 @@ BasedOnStyle: LLVM -IndentWidth: 4 +IndentWidth: 2 PointerAlignment: Left +ColumnLimit: 100 +AccessModifierOffset: -2 From ccac52e71834078f9f23ca55f93e8abd71656c59 Mon Sep 17 00:00:00 2001 From: Artemis Rosman <73006620+rozukke@users.noreply.github.com> Date: Sat, 15 Feb 2025 16:49:28 +1100 Subject: [PATCH 13/19] chore: update formatting --- example/game-of-life/game_of_life.cpp | 337 +++++---- example/hello_minecraft.cpp | 6 +- example/minesweeper/minesweeper.cpp | 699 +++++++++--------- example/model-generation/obj-mc.cpp | 309 ++++---- example/pyramid.cpp | 49 +- example/video-generation/video-mc.cpp | 373 +++++----- include/mcpp/block.h | 978 +++++++++++++------------- 7 files changed, 1357 insertions(+), 1394 deletions(-) diff --git a/example/game-of-life/game_of_life.cpp b/example/game-of-life/game_of_life.cpp index 76d5e81..f66793a 100644 --- a/example/game-of-life/game_of_life.cpp +++ b/example/game-of-life/game_of_life.cpp @@ -4,209 +4,200 @@ #include class Life { - private: - int width, depth; - int** game; // 1 is active - bool isRunning; - int delay; - - const mcpp::BlockType PLAY_BLOCK = mcpp::Blocks::GREEN_CONCRETE; - const mcpp::BlockType PAUSE_BLOCK = mcpp::Blocks::RED_CONCRETE; - const mcpp::BlockType DEAD_BLOCK = mcpp::Blocks::BLACK_CONCRETE; - const mcpp::BlockType ALIVE_BLOCK = mcpp::Blocks::WHITE_CONCRETE; - const mcpp::BlockType SPEED_BLOCK = mcpp::Blocks::YELLOW_CONCRETE; - const mcpp::BlockType SLOW_BLOCK = mcpp::Blocks::BLUE_CONCRETE; - const mcpp::BlockType RANDOM_BLOCK = mcpp::Blocks::PINK_CONCRETE; - const mcpp::BlockType CLEAR_BLOCK = mcpp::Blocks::BARRIER; - - mcpp::Coordinate buildPosition, bounds, upperBuildPosition, upperBounds; - - mcpp::MinecraftConnection mc; - - int GetNeighbors(int x, int y); - - public: - Life(int width, int depth); - ~Life(); - - void Update(); - - void Pause() { isRunning = false; }; - void Play() { isRunning = true; }; - void Delay() { - std::this_thread::sleep_for(std::chrono::milliseconds(delay)); - }; -}; +private: + int width, depth; + int** game; // 1 is active + bool isRunning; + int delay; -int main(int argc, char* argv[]) { - int width = 40; - int depth = 40; - if (argc >= 2) { - width = atoi(argv[1]); - depth = atoi(argv[1]); - } - if (argc >= 3) { - depth = atoi(argv[2]); - } + const mcpp::BlockType PLAY_BLOCK = mcpp::Blocks::GREEN_CONCRETE; + const mcpp::BlockType PAUSE_BLOCK = mcpp::Blocks::RED_CONCRETE; + const mcpp::BlockType DEAD_BLOCK = mcpp::Blocks::BLACK_CONCRETE; + const mcpp::BlockType ALIVE_BLOCK = mcpp::Blocks::WHITE_CONCRETE; + const mcpp::BlockType SPEED_BLOCK = mcpp::Blocks::YELLOW_CONCRETE; + const mcpp::BlockType SLOW_BLOCK = mcpp::Blocks::BLUE_CONCRETE; + const mcpp::BlockType RANDOM_BLOCK = mcpp::Blocks::PINK_CONCRETE; + const mcpp::BlockType CLEAR_BLOCK = mcpp::Blocks::BARRIER; - Life life(width, depth); + mcpp::Coordinate buildPosition, bounds, upperBuildPosition, upperBounds; - while (true) - life.Update(); + mcpp::MinecraftConnection mc; - return 0; + int GetNeighbors(int x, int y); + +public: + Life(int width, int depth); + ~Life(); + + void Update(); + + void Pause() { isRunning = false; }; + void Play() { isRunning = true; }; + void Delay() { std::this_thread::sleep_for(std::chrono::milliseconds(delay)); }; +}; + +int main(int argc, char* argv[]) { + int width = 40; + int depth = 40; + if (argc >= 2) { + width = atoi(argv[1]); + depth = atoi(argv[1]); + } + if (argc >= 3) { + depth = atoi(argv[2]); + } + + Life life(width, depth); + + while (true) + life.Update(); + + return 0; } -Life::Life(int width, int depth) - : width(width), depth(depth), isRunning(false), delay(250) { - buildPosition = mc.getPlayerPosition(); - buildPosition.y -= 5; - buildPosition.x -= width / 2; - buildPosition.z -= depth / 2; - - bounds = mcpp::Coordinate(buildPosition.x + width - 1, buildPosition.y, - buildPosition.z + depth - 1); - upperBounds = - mcpp::Coordinate(buildPosition.x + width - 1, buildPosition.y + 1, - buildPosition.z + depth - 1); - upperBuildPosition = - mcpp::Coordinate(buildPosition.x, buildPosition.y + 1, buildPosition.z); - - game = new int*[width]; - for (int x = 0; x < width; x++) { - game[x] = new int[depth]; - for (int y = 0; y < depth; y++) { - game[x][y] = 0; - } +Life::Life(int width, int depth) : width(width), depth(depth), isRunning(false), delay(250) { + buildPosition = mc.getPlayerPosition(); + buildPosition.y -= 5; + buildPosition.x -= width / 2; + buildPosition.z -= depth / 2; + + bounds = + mcpp::Coordinate(buildPosition.x + width - 1, buildPosition.y, buildPosition.z + depth - 1); + upperBounds = mcpp::Coordinate(buildPosition.x + width - 1, buildPosition.y + 1, + buildPosition.z + depth - 1); + upperBuildPosition = mcpp::Coordinate(buildPosition.x, buildPosition.y + 1, buildPosition.z); + + game = new int*[width]; + for (int x = 0; x < width; x++) { + game[x] = new int[depth]; + for (int y = 0; y < depth; y++) { + game[x][y] = 0; } - - mc.doCommand("clear @p"); - mc.doCommand("give @p minecraft:white_concrete"); - mc.doCommand("give @p minecraft:black_concrete"); - mc.doCommand("give @p minecraft:green_concrete"); - mc.doCommand("give @p minecraft:red_concrete"); - mc.doCommand("give @p minecraft:yellow_concrete"); - mc.doCommand("give @p minecraft:blue_concrete"); - mc.doCommand("give @p minecraft:pink_concrete"); - mc.doCommand("give @p minecraft:barrier"); + } + + mc.doCommand("clear @p"); + mc.doCommand("give @p minecraft:white_concrete"); + mc.doCommand("give @p minecraft:black_concrete"); + mc.doCommand("give @p minecraft:green_concrete"); + mc.doCommand("give @p minecraft:red_concrete"); + mc.doCommand("give @p minecraft:yellow_concrete"); + mc.doCommand("give @p minecraft:blue_concrete"); + mc.doCommand("give @p minecraft:pink_concrete"); + mc.doCommand("give @p minecraft:barrier"); } Life::~Life() { - for (int x = 0; x < width; x++) { - delete[] game[x]; - } - delete[] game; + for (int x = 0; x < width; x++) { + delete[] game[x]; + } + delete[] game; } void Life::Update() { - // check for actions - mcpp::Chunk chunk = mc.getBlocks(upperBuildPosition, upperBounds); - for (int x = 0; x < width; x++) { - for (int z = 0; z < depth; z++) { - mcpp::BlockType block = chunk.get(x, 0, z); - - mcpp::Coordinate position(upperBuildPosition.x + x, - upperBuildPosition.y, - upperBuildPosition.z + z); - if (block != mcpp::Blocks::AIR) { - mc.setBlock(position, mcpp::Blocks::AIR); - } - - if (block == PLAY_BLOCK) { - Play(); - mc.postToChat("Playing"); - } else if (block == PAUSE_BLOCK) { - Pause(); - mc.postToChat("Pausing"); - } else if (block == ALIVE_BLOCK) { - game[x][z] = 1; - } else if (block == DEAD_BLOCK) { - game[x][z] = 0; - } else if (block == SPEED_BLOCK) { - delay = std::max(delay / 2, 1); - mc.postToChat("Speeding up"); - } else if (block == SLOW_BLOCK) { - delay *= 2; - mc.postToChat("Slowing down"); - } else if (block == RANDOM_BLOCK) { - for (int x = 0; x < width; x++) { - for (int z = 0; z < depth; z++) { - game[x][z] = rand() % 2; - } - } - mc.postToChat("Randomizing"); - } else if (block == CLEAR_BLOCK) { - for (int x = 0; x < width; x++) { - for (int z = 0; z < depth; z++) { - game[x][z] = 0; - } - } - mc.postToChat("Clearing"); - } - } - } - - if (isRunning) { - // neighbor counts - int** neighbors = new int*[width]; + // check for actions + mcpp::Chunk chunk = mc.getBlocks(upperBuildPosition, upperBounds); + for (int x = 0; x < width; x++) { + for (int z = 0; z < depth; z++) { + mcpp::BlockType block = chunk.get(x, 0, z); + + mcpp::Coordinate position(upperBuildPosition.x + x, upperBuildPosition.y, + upperBuildPosition.z + z); + if (block != mcpp::Blocks::AIR) { + mc.setBlock(position, mcpp::Blocks::AIR); + } + + if (block == PLAY_BLOCK) { + Play(); + mc.postToChat("Playing"); + } else if (block == PAUSE_BLOCK) { + Pause(); + mc.postToChat("Pausing"); + } else if (block == ALIVE_BLOCK) { + game[x][z] = 1; + } else if (block == DEAD_BLOCK) { + game[x][z] = 0; + } else if (block == SPEED_BLOCK) { + delay = std::max(delay / 2, 1); + mc.postToChat("Speeding up"); + } else if (block == SLOW_BLOCK) { + delay *= 2; + mc.postToChat("Slowing down"); + } else if (block == RANDOM_BLOCK) { for (int x = 0; x < width; x++) { - neighbors[x] = new int[depth]; - for (int y = 0; y < depth; y++) { - neighbors[x][y] = GetNeighbors(x, y); - } + for (int z = 0; z < depth; z++) { + game[x][z] = rand() % 2; + } } - - // next generation state + mc.postToChat("Randomizing"); + } else if (block == CLEAR_BLOCK) { for (int x = 0; x < width; x++) { - for (int z = 0; z < depth; z++) { - if (game[x][z] == 1) { - if (neighbors[x][z] < 2) { - game[x][z] = 0; - } else if (neighbors[x][z] > 3) { - game[x][z] = 0; - } - } else if (neighbors[x][z] == 3) { - game[x][z] = 1; - } - } + for (int z = 0; z < depth; z++) { + game[x][z] = 0; + } } + mc.postToChat("Clearing"); + } + } + } - for (int x = 0; x < width; x++) { - delete[] neighbors[x]; - } - delete[] neighbors; + if (isRunning) { + // neighbor counts + int** neighbors = new int*[width]; + for (int x = 0; x < width; x++) { + neighbors[x] = new int[depth]; + for (int y = 0; y < depth; y++) { + neighbors[x][y] = GetNeighbors(x, y); + } } - // draw - mc.setBlocks(buildPosition, bounds, DEAD_BLOCK); + // next generation state for (int x = 0; x < width; x++) { - for (int z = 0; z < depth; z++) { - mcpp::Coordinate position(buildPosition.x + x, buildPosition.y, - buildPosition.z + z); - if (game[x][z] == 1) { - mc.setBlock(position, ALIVE_BLOCK); - } + for (int z = 0; z < depth; z++) { + if (game[x][z] == 1) { + if (neighbors[x][z] < 2) { + game[x][z] = 0; + } else if (neighbors[x][z] > 3) { + game[x][z] = 0; + } + } else if (neighbors[x][z] == 3) { + game[x][z] = 1; } + } } - Delay(); + for (int x = 0; x < width; x++) { + delete[] neighbors[x]; + } + delete[] neighbors; + } + + // draw + mc.setBlocks(buildPosition, bounds, DEAD_BLOCK); + for (int x = 0; x < width; x++) { + for (int z = 0; z < depth; z++) { + mcpp::Coordinate position(buildPosition.x + x, buildPosition.y, buildPosition.z + z); + if (game[x][z] == 1) { + mc.setBlock(position, ALIVE_BLOCK); + } + } + } + + Delay(); } int Life::GetNeighbors(int x, int y) { - int alive = 0; + int alive = 0; - int neighbors[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, - {0, 1}, {1, -1}, {1, 0}, {1, 1}}; + int neighbors[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; - for (int i = 0; i < 8; i++) { - int nx = x + neighbors[i][0]; - int ny = y + neighbors[i][1]; + for (int i = 0; i < 8; i++) { + int nx = x + neighbors[i][0]; + int ny = y + neighbors[i][1]; - if (nx >= 0 && nx < width && ny >= 0 && ny < depth && - game[nx][ny] == 1) { - alive++; - } + if (nx >= 0 && nx < width && ny >= 0 && ny < depth && game[nx][ny] == 1) { + alive++; } + } - return alive; + return alive; } \ No newline at end of file diff --git a/example/hello_minecraft.cpp b/example/hello_minecraft.cpp index 37c4bf6..19fcb0b 100644 --- a/example/hello_minecraft.cpp +++ b/example/hello_minecraft.cpp @@ -3,8 +3,8 @@ using namespace mcpp; int main() { - MinecraftConnection mc; + MinecraftConnection mc; - // Post chat to Minecraft - mc.postToChat("Hello, Minecraft!"); + // Post chat to Minecraft + mc.postToChat("Hello, Minecraft!"); } diff --git a/example/minesweeper/minesweeper.cpp b/example/minesweeper/minesweeper.cpp index 8f0a611..e43ff06 100644 --- a/example/minesweeper/minesweeper.cpp +++ b/example/minesweeper/minesweeper.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -12,416 +13,412 @@ #define badmine mcpp::Blocks::MAGMA_BLOCK class Minesweeper { - private: - const int X_SIZE = 10; - const int Z_SIZE = 10; - const int MINE_COUNT = 20; - - int*** field; - int clearstowin; - int flagsleft; - bool playing; - bool firstclick; - - std::vector blocks; - std::vector numbers; - - mcpp::MinecraftConnection mc; - mcpp::Coordinate origin; - mcpp::Coordinate cornerOrigin; - mcpp::Coordinate cornerOpposite; - mcpp::Coordinate printer; - mcpp::Coordinate displayclearsorigin; - mcpp::Coordinate displayflagsorigin; - - public: - Minesweeper(); - bool Playing(); - void Flag(int x, int z); - void Clear(int x, int z); - void ZeroClear(int x, int z); - void Reveal(); - void FirstClickProtection(int x, int z); - void UpdateDisplays(); - void MakeMines(int minecount, int x, int z); - void GenerateBoard(); - void ResetField(); - bool GameLoop(); +private: + const int X_SIZE = 10; + const int Z_SIZE = 10; + const int MINE_COUNT = 20; + + int*** field; + int clearstowin; + int flagsleft; + bool playing; + bool firstclick; + + std::vector blocks; + std::vector numbers; + + mcpp::MinecraftConnection mc; + mcpp::Coordinate origin; + mcpp::Coordinate cornerOrigin; + mcpp::Coordinate cornerOpposite; + mcpp::Coordinate printer; + mcpp::Coordinate displayclearsorigin; + mcpp::Coordinate displayflagsorigin; + +public: + Minesweeper(); + bool Playing(); + void Flag(int x, int z); + void Clear(int x, int z); + void ZeroClear(int x, int z); + void Reveal(); + void FirstClickProtection(int x, int z); + void UpdateDisplays(); + void MakeMines(int minecount, int x, int z); + void GenerateBoard(); + void ResetField(); + bool GameLoop(); }; int main() { - Minesweeper ms; - ms.GameLoop(); - std::cout << "Done" << std::endl; + Minesweeper ms; + ms.GameLoop(); + std::cout << "Done" << std::endl; } bool Minesweeper::GameLoop() { - while (Playing()) { - // std::cout<<"Tick"< 10 || - fabs(playerpos.z - origin.z) - Z_SIZE > 10) { - mc.postToChat("Left player area. Quitting."); - finish = false; - } + mcpp::Coordinate playerpos = mc.getPlayerPosition(); + if (fabs(playerpos.x - origin.x) - X_SIZE > 10 || fabs(playerpos.z - origin.z) - Z_SIZE > 10) { + mc.postToChat("Left player area. Quitting."); + finish = false; } - return false; + } + return false; } Minesweeper::Minesweeper() { - // field[X_SIZE][Z_SIZE][STATE] - // State [0] values 0-9 representing how many mines around it, 9=mine - // State [1] (0) = none (1) = flag (2) = cleared - field = new int**[X_SIZE]; - for (int i = 0; i < X_SIZE; i++) { - field[i] = new int*[Z_SIZE]; - for (int j = 0; j < Z_SIZE; j++) { - field[i][j] = new int[2]{0, 0}; - } + // field[X_SIZE][Z_SIZE][STATE] + // State [0] values 0-9 representing how many mines around it, 9=mine + // State [1] (0) = none (1) = flag (2) = cleared + field = new int**[X_SIZE]; + for (int i = 0; i < X_SIZE; i++) { + field[i] = new int*[Z_SIZE]; + for (int j = 0; j < Z_SIZE; j++) { + field[i][j] = new int[2]{0, 0}; } - // Block Representations numbers 0-9 - blocks = {mcpp::Blocks::WHITE_CONCRETE, mcpp::Blocks::LIGHT_BLUE_CONCRETE, - mcpp::Blocks::CYAN_CONCRETE, mcpp::Blocks::GREEN_CONCRETE, - mcpp::Blocks::LIME_CONCRETE, mcpp::Blocks::YELLOW_CONCRETE, - mcpp::Blocks::ORANGE_CONCRETE, mcpp::Blocks::RED_CONCRETE, - mcpp::Blocks::BROWN_CONCRETE, mcpp::Blocks::TNT}; - - numbers = {mcpp::Blocks::WHITE_WOOL, mcpp::Blocks::LIGHT_BLUE_WOOL, - mcpp::Blocks::CYAN_WOOL, mcpp::Blocks::GREEN_WOOL, - mcpp::Blocks::LIME_WOOL, mcpp::Blocks::YELLOW_WOOL, - mcpp::Blocks::ORANGE_WOOL, mcpp::Blocks::RED_WOOL, - mcpp::Blocks::BROWN_WOOL, mcpp::Blocks::BLACK_WOOL}; - - // Gives player items to play - mc.doCommand("gamerule sendCommandFeedback false"); - mc.doCommand("clear @p"); - mc.doCommand("give @p tnt"); - mc.doCommand("give @p sea_lantern"); - mc.doCommand("give @p barrier"); - mc.doCommand("gamerule sendCommandFeedback true"); - // Lets player know how to play - mc.postToChat("The TNT/Mine clears the spot below"); - mc.postToChat("The Sea_Lantern/Flag flags the spot below"); - mc.postToChat("The barrier exits the game"); - mc.postToChat("To play, place blocks above the board"); - - // Builds board - origin = mc.getPlayerTilePosition(); - GenerateBoard(); - - // Prints the legend - printer = origin; - printer.z--; - printer.y++; - for (int i = 0; i <= 9; i++) { - mc.setBlock(printer, blocks[i]); - printer.x++; - } - mc.setBlock(printer, flag); - printer.y++; - mc.setBlock(printer, badflag); - printer.x--; - mc.setBlock(printer, goodmine); - printer.y++; - mc.setBlock(printer, badmine); - - // Sets the display origins and keys - displayclearsorigin = origin; - displayclearsorigin.z--; - displayclearsorigin.y += 3; - mc.setBlock(displayclearsorigin, uncleared); - displayclearsorigin.x++; - - displayflagsorigin = displayclearsorigin; - displayflagsorigin.x += 4; - mc.setBlock(displayflagsorigin, flag); - displayflagsorigin.x++; + } + // Block Representations numbers 0-9 + blocks = {mcpp::Blocks::WHITE_CONCRETE, mcpp::Blocks::LIGHT_BLUE_CONCRETE, + mcpp::Blocks::CYAN_CONCRETE, mcpp::Blocks::GREEN_CONCRETE, + mcpp::Blocks::LIME_CONCRETE, mcpp::Blocks::YELLOW_CONCRETE, + mcpp::Blocks::ORANGE_CONCRETE, mcpp::Blocks::RED_CONCRETE, + mcpp::Blocks::BROWN_CONCRETE, mcpp::Blocks::TNT}; + + numbers = {mcpp::Blocks::WHITE_WOOL, mcpp::Blocks::LIGHT_BLUE_WOOL, mcpp::Blocks::CYAN_WOOL, + mcpp::Blocks::GREEN_WOOL, mcpp::Blocks::LIME_WOOL, mcpp::Blocks::YELLOW_WOOL, + mcpp::Blocks::ORANGE_WOOL, mcpp::Blocks::RED_WOOL, mcpp::Blocks::BROWN_WOOL, + mcpp::Blocks::BLACK_WOOL}; + + // Gives player items to play + mc.doCommand("gamerule sendCommandFeedback false"); + mc.doCommand("clear @p"); + mc.doCommand("give @p tnt"); + mc.doCommand("give @p sea_lantern"); + mc.doCommand("give @p barrier"); + mc.doCommand("gamerule sendCommandFeedback true"); + // Lets player know how to play + mc.postToChat("The TNT/Mine clears the spot below"); + mc.postToChat("The Sea_Lantern/Flag flags the spot below"); + mc.postToChat("The barrier exits the game"); + mc.postToChat("To play, place blocks above the board"); + + // Builds board + origin = mc.getPlayerTilePosition(); + GenerateBoard(); + + // Prints the legend + printer = origin; + printer.z--; + printer.y++; + for (int i = 0; i <= 9; i++) { + mc.setBlock(printer, blocks[i]); + printer.x++; + } + mc.setBlock(printer, flag); + printer.y++; + mc.setBlock(printer, badflag); + printer.x--; + mc.setBlock(printer, goodmine); + printer.y++; + mc.setBlock(printer, badmine); + + // Sets the display origins and keys + displayclearsorigin = origin; + displayclearsorigin.z--; + displayclearsorigin.y += 3; + mc.setBlock(displayclearsorigin, uncleared); + displayclearsorigin.x++; + + displayflagsorigin = displayclearsorigin; + displayflagsorigin.x += 4; + mc.setBlock(displayflagsorigin, flag); + displayflagsorigin.x++; } bool Minesweeper::Playing() { - mcpp::Chunk choices = mc.getBlocks(cornerOrigin, cornerOpposite); - for (int x = 0; x < X_SIZE; x++) { - for (int z = 0; z < Z_SIZE; z++) { - printer.x = origin.x + x; - printer.z = origin.z + z; - printer.y = origin.y; // Set printer pos - - if (choices.get(x, 0, z) == clear) { - Clear(x, z); - } else if (choices.get(x, 0, z) == flag) { - Flag(x, z); - } else if (choices.get(x, 0, z) == quit) { - playing = false; - printer.y++; - mc.setBlock(printer, air); - mc.postToChat("Quitting"); - } - } - } - - if (clearstowin == 0) { - mc.postToChat("YOU WIN!!"); + mcpp::Chunk choices = mc.getBlocks(cornerOrigin, cornerOpposite); + for (int x = 0; x < X_SIZE; x++) { + for (int z = 0; z < Z_SIZE; z++) { + printer.x = origin.x + x; + printer.z = origin.z + z; + printer.y = origin.y; // Set printer pos + + if (choices.get(x, 0, z) == clear) { + Clear(x, z); + } else if (choices.get(x, 0, z) == flag) { + Flag(x, z); + } else if (choices.get(x, 0, z) == quit) { playing = false; + printer.y++; + mc.setBlock(printer, air); + mc.postToChat("Quitting"); + } } + } - return playing; + if (clearstowin == 0) { + mc.postToChat("YOU WIN!!"); + playing = false; + } + + return playing; } void Minesweeper::Flag(int x, int z) { - if (field[x][z][1] == 0) { - field[x][z][1] = 1; - flagsleft--; - mc.setBlock(printer, flag); - } else if (field[x][z][1] == 1) { - field[x][z][1] = 0; - flagsleft++; - mc.setBlock(printer, uncleared); - } - - printer.y++; - mc.setBlock(printer, air); + if (field[x][z][1] == 0) { + field[x][z][1] = 1; + flagsleft--; + mc.setBlock(printer, flag); + } else if (field[x][z][1] == 1) { + field[x][z][1] = 0; + flagsleft++; + mc.setBlock(printer, uncleared); + } + + printer.y++; + mc.setBlock(printer, air); } void Minesweeper::Clear(int x, int z) { - if (field[x][z][1] == 0) { - - mc.setBlock(printer, blocks[field[x][z][0]]); - - if (field[x][z][0] == 9) { // If a mine, you loose - if (firstclick) { - firstclick = false; - FirstClickProtection(x, z); - Clear(x, z); - } else { - mc.postToChat("GAMEOVER!"); - playing = false; - } - } else if (field[x][z][0] == 0) { // If zero add location to a stack - ZeroClear(x, z); - } + if (field[x][z][1] == 0) { - if (field[x][z][1] != 2) { - clearstowin--; - } + mc.setBlock(printer, blocks[field[x][z][0]]); - field[x][z][1] = 2; + if (field[x][z][0] == 9) { // If a mine, you loose + if (firstclick) { firstclick = false; + FirstClickProtection(x, z); + Clear(x, z); + } else { + mc.postToChat("GAMEOVER!"); + playing = false; + } + } else if (field[x][z][0] == 0) { // If zero add location to a stack + ZeroClear(x, z); + } + + if (field[x][z][1] != 2) { + clearstowin--; } - printer.y++; // removes block above the board - mc.setBlock(printer, air); + field[x][z][1] = 2; + firstclick = false; + } + + printer.y++; // removes block above the board + mc.setBlock(printer, air); } void Minesweeper::ZeroClear(int x, int z) { - std::vector stack = {new int[2]{x, z}}; - size_t pos = 0; - - while (pos < stack.size()) { - int* zeroCoordinate = stack.at(pos); - int xC = zeroCoordinate[0]; - int zC = zeroCoordinate[1]; - for (int xo = -1; xo <= 1; xo++) { - for (int zo = -1; zo <= 1; zo++) { - if (xC + xo >= 0 && xC + xo < X_SIZE && zC + zo >= 0 && - zC + zo < Z_SIZE) { - - if (field[xC + xo][zC + zo][0] == 0 && - field[xC + xo][zC + zo][1] != 2) { - stack.push_back(new int[2]{xC + xo, zC + zo}); - } - - printer.x = origin.x + xC + xo; - printer.z = origin.z + zC + zo; - mc.setBlock(printer, blocks[field[xC + xo][zC + zo][0]]); - - if (field[xC + xo][zC + zo][1] != 2) { - clearstowin--; - } - - field[xC + xo][zC + zo][1] = 2; - } - } + std::vector stack = {new int[2]{x, z}}; + size_t pos = 0; + + while (pos < stack.size()) { + int* zeroCoordinate = stack.at(pos); + int xC = zeroCoordinate[0]; + int zC = zeroCoordinate[1]; + for (int xo = -1; xo <= 1; xo++) { + for (int zo = -1; zo <= 1; zo++) { + if (xC + xo >= 0 && xC + xo < X_SIZE && zC + zo >= 0 && zC + zo < Z_SIZE) { + + if (field[xC + xo][zC + zo][0] == 0 && field[xC + xo][zC + zo][1] != 2) { + stack.push_back(new int[2]{xC + xo, zC + zo}); + } + + printer.x = origin.x + xC + xo; + printer.z = origin.z + zC + zo; + mc.setBlock(printer, blocks[field[xC + xo][zC + zo][0]]); + + if (field[xC + xo][zC + zo][1] != 2) { + clearstowin--; + } + + field[xC + xo][zC + zo][1] = 2; } - pos++; + } } + pos++; + } } void Minesweeper::Reveal() { - printer = origin; - for (int x = 0; x < X_SIZE; x++) { // Steps through the whole board - for (int z = 0; z < Z_SIZE; z++) { // shows what you did correctly and - if (field[x][z][0] == 9) { // incorrectly - if (field[x][z][1] == 1) { - mc.setBlock(printer, goodmine); - } else if (field[x][z][1] == 0) { - mc.setBlock(printer, clear); - } else { - mc.setBlock(printer, badmine); - } - } else if (field[x][z][1] == 1) { - mc.setBlock(printer, badflag); - } - printer.z++; + printer = origin; + for (int x = 0; x < X_SIZE; x++) { // Steps through the whole board + for (int z = 0; z < Z_SIZE; z++) { // shows what you did correctly and + if (field[x][z][0] == 9) { // incorrectly + if (field[x][z][1] == 1) { + mc.setBlock(printer, goodmine); + } else if (field[x][z][1] == 0) { + mc.setBlock(printer, clear); + } else { + mc.setBlock(printer, badmine); } - printer.z = origin.z; - printer.x++; + } else if (field[x][z][1] == 1) { + mc.setBlock(printer, badflag); + } + printer.z++; } + printer.z = origin.z; + printer.x++; + } } void Minesweeper::FirstClickProtection(int x, int z) { - mc.postToChat("Saved, Would have been a mine"); - field[x][z][0] = 1; - - for (int xo = -1; xo <= 1; xo++) { - for (int zo = -1; zo <= 1; zo++) { - if (field[x + xo][z + zo][0] == 9) { - field[x][z][0]++; - } else { - field[x + xo][z + zo][0]--; - } - } + mc.postToChat("Saved, Would have been a mine"); + field[x][z][0] = 1; + + for (int xo = -1; xo <= 1; xo++) { + for (int zo = -1; zo <= 1; zo++) { + if (field[x + xo][z + zo][0] == 9) { + field[x][z][0]++; + } else { + field[x + xo][z + zo][0]--; + } } + } - MakeMines(1, x, z); + MakeMines(1, x, z); } void Minesweeper::UpdateDisplays() { - printer = displayclearsorigin; - printer.x += 3; - mc.setBlocks(printer, displayclearsorigin, air); - printer.x -= 3; - - if (clearstowin >= 1000) { - mc.setBlock(printer, numbers[clearstowin / 1000]); - printer.x++; - } - if (clearstowin >= 100) { - mc.setBlock(printer, numbers[(clearstowin % 1000) / 100]); - printer.x++; - } - if (clearstowin >= 10) { - mc.setBlock(printer, numbers[(clearstowin % 100) / 10]); - printer.x++; - } - if (clearstowin >= 1) { - mc.setBlock(printer, numbers[clearstowin % 10]); - printer.x++; - } - - printer = displayflagsorigin; - printer.x += 2; - mc.setBlocks(printer, displayflagsorigin, air); - printer.x -= 2; - if (flagsleft >= 1000) { - mc.setBlock(printer, numbers[flagsleft / 1000]); - printer.x++; - } - if (flagsleft >= 100) { - mc.setBlock(printer, numbers[(flagsleft % 1000) / 100]); - printer.x++; - } - if (flagsleft >= 10) { - mc.setBlock(printer, numbers[(flagsleft % 100) / 10]); - printer.x++; - } - if (flagsleft >= 1) { - mc.setBlock(printer, numbers[flagsleft % 10]); - printer.x++; - } + printer = displayclearsorigin; + printer.x += 3; + mc.setBlocks(printer, displayclearsorigin, air); + printer.x -= 3; + + if (clearstowin >= 1000) { + mc.setBlock(printer, numbers[clearstowin / 1000]); + printer.x++; + } + if (clearstowin >= 100) { + mc.setBlock(printer, numbers[(clearstowin % 1000) / 100]); + printer.x++; + } + if (clearstowin >= 10) { + mc.setBlock(printer, numbers[(clearstowin % 100) / 10]); + printer.x++; + } + if (clearstowin >= 1) { + mc.setBlock(printer, numbers[clearstowin % 10]); + printer.x++; + } + + printer = displayflagsorigin; + printer.x += 2; + mc.setBlocks(printer, displayflagsorigin, air); + printer.x -= 2; + if (flagsleft >= 1000) { + mc.setBlock(printer, numbers[flagsleft / 1000]); + printer.x++; + } + if (flagsleft >= 100) { + mc.setBlock(printer, numbers[(flagsleft % 1000) / 100]); + printer.x++; + } + if (flagsleft >= 10) { + mc.setBlock(printer, numbers[(flagsleft % 100) / 10]); + printer.x++; + } + if (flagsleft >= 1) { + mc.setBlock(printer, numbers[flagsleft % 10]); + printer.x++; + } } void Minesweeper::MakeMines(int mineamount, int xS, int zS) { - for (int mines = 0; mines < mineamount; mines++) { - int x = rand() % X_SIZE; - int z = rand() % Z_SIZE; - - if (field[x][z][0] != 9 && (x != xS || z != zS)) { - field[x][z][0] = 9; - - for (int xOfset = -1; xOfset <= 1; xOfset++) { - if (x + xOfset >= 0 && x + xOfset < X_SIZE) { - for (int zOfset = -1; zOfset <= 1; zOfset++) { - if (z + zOfset >= 0 && z + zOfset < Z_SIZE) { - if (field[x + xOfset][z + zOfset][0] != 9) { - field[x + xOfset][z + zOfset][0]++; - } - } - } - } + for (int mines = 0; mines < mineamount; mines++) { + int x = rand() % X_SIZE; + int z = rand() % Z_SIZE; + + if (field[x][z][0] != 9 && (x != xS || z != zS)) { + field[x][z][0] = 9; + + for (int xOfset = -1; xOfset <= 1; xOfset++) { + if (x + xOfset >= 0 && x + xOfset < X_SIZE) { + for (int zOfset = -1; zOfset <= 1; zOfset++) { + if (z + zOfset >= 0 && z + zOfset < Z_SIZE) { + if (field[x + xOfset][z + zOfset][0] != 9) { + field[x + xOfset][z + zOfset][0]++; + } } - } else { // If a mine is already in the place make another mine - mines--; + } } + } + } else { // If a mine is already in the place make another mine + mines--; } + } } void Minesweeper::GenerateBoard() { - // Resets Field - ResetField(); - - cornerOrigin = origin; - cornerOpposite = origin; - cornerOpposite.x += X_SIZE - 1; - cornerOpposite.z += Z_SIZE - 1; - mc.setBlocks(cornerOrigin, cornerOpposite, uncleared); - - // Moves corners up for later use in grabbing game area; - cornerOpposite.y++; - cornerOrigin.y++; - - // Generates mines and increases values around mines by 1 - srand(time(nullptr)); - MakeMines(MINE_COUNT, -1, -1); - // This value counts down until you are finished clearing the field - clearstowin = X_SIZE * Z_SIZE - MINE_COUNT; - - // Defaults bools - playing = true; - firstclick = true; - - // Defaults - flagsleft = MINE_COUNT; + // Resets Field + ResetField(); + + cornerOrigin = origin; + cornerOpposite = origin; + cornerOpposite.x += X_SIZE - 1; + cornerOpposite.z += Z_SIZE - 1; + mc.setBlocks(cornerOrigin, cornerOpposite, uncleared); + + // Moves corners up for later use in grabbing game area; + cornerOpposite.y++; + cornerOrigin.y++; + + // Generates mines and increases values around mines by 1 + srand(time(nullptr)); + MakeMines(MINE_COUNT, -1, -1); + // This value counts down until you are finished clearing the field + clearstowin = X_SIZE * Z_SIZE - MINE_COUNT; + + // Defaults bools + playing = true; + firstclick = true; + + // Defaults + flagsleft = MINE_COUNT; } void Minesweeper::ResetField() { - for (int x = 0; x < X_SIZE; x++) { - for (int z = 0; z < Z_SIZE; z++) { - field[x][z][0] = 0; - field[x][z][1] = 0; - } + for (int x = 0; x < X_SIZE; x++) { + for (int z = 0; z < Z_SIZE; z++) { + field[x][z][0] = 0; + field[x][z][1] = 0; } + } } diff --git a/example/model-generation/obj-mc.cpp b/example/model-generation/obj-mc.cpp index ed31f56..a25c852 100644 --- a/example/model-generation/obj-mc.cpp +++ b/example/model-generation/obj-mc.cpp @@ -1,226 +1,217 @@ -#include #include #include +#include #include #include -#include #include struct Vec3 { - float x, y, z; + float x, y, z; }; struct Face { - int first, second, third; + int first, second, third; }; class Model { - public: - Model(const std::string& filename); - ~Model() { - if (_file.is_open()) { - _file.close(); - } +public: + Model(const std::string& filename); + ~Model() { + if (_file.is_open()) { + _file.close(); } + } - void BuildModel(mcpp::MinecraftConnection& mc); - void BuildPointCloud(mcpp::MinecraftConnection& mc); + void BuildModel(mcpp::MinecraftConnection& mc); + void BuildPointCloud(mcpp::MinecraftConnection& mc); - void Scale(int scale); - void SetPosition(mcpp::Coordinate position); + void Scale(int scale); + void SetPosition(mcpp::Coordinate position); - private: - bool IsWithin(Vec3& position); +private: + bool IsWithin(Vec3& position); - Vec3 sub(Vec3 a, Vec3 b); - float dot(Vec3 a, Vec3 b); - Vec3 cross(Vec3 a, Vec3 b); + Vec3 sub(Vec3 a, Vec3 b); + float dot(Vec3 a, Vec3 b); + Vec3 cross(Vec3 a, Vec3 b); - std::ifstream _file; + std::ifstream _file; - std::vector _vertices; - std::vector _faces; + std::vector _vertices; + std::vector _faces; - mcpp::Coordinate _position; + mcpp::Coordinate _position; }; int main(int argc, char* argv[]) { - if (argc < 3) { - std::cerr << "Usage: " << argv[0] << " filename.obj scale" << std::endl; - return 1; - } + if (argc < 3) { + std::cerr << "Usage: " << argv[0] << " filename.obj scale" << std::endl; + return 1; + } - std::string filename = argv[1]; - int scale = std::stoi(argv[2]); + std::string filename = argv[1]; + int scale = std::stoi(argv[2]); - mcpp::MinecraftConnection mc; + mcpp::MinecraftConnection mc; - Model* model = new Model(filename); - model->SetPosition(mc.getPlayerPosition()); - model->Scale(scale); - model->BuildModel(mc); // Fills the model - model->BuildPointCloud(mc); // Places blocks at vertices + Model* model = new Model(filename); + model->SetPosition(mc.getPlayerPosition()); + model->Scale(scale); + model->BuildModel(mc); // Fills the model + model->BuildPointCloud(mc); // Places blocks at vertices - return 0; + return 0; } Model::Model(const std::string& filename) { - _file.open(filename, std::ios::binary); - if (!_file.is_open()) { - throw std::runtime_error("Error opening file"); - } - - std::string line; - while (std::getline(_file, line)) { - if (line.substr(0, 2) == "v ") { - Vec3 vertex; - std::sscanf(line.c_str(), "v %f %f %f", &vertex.x, &vertex.y, - &vertex.z); - _vertices.push_back(vertex); - } else if (line.substr(0, 2) == "f ") { - Face face; - if (line.find(std::string("//")) != std::string::npos) { - std::sscanf(line.c_str(), "f %d//%*d %d//%*d %d//%*d", - &face.first, &face.second, &face.third); - } else if (line.find(std::string("/")) != std::string::npos) { - std::sscanf(line.c_str(), "f %d/%*d/%*d %d/%*d/%*d %d/%*d/%*d", - &face.first, &face.second, &face.third); - } else { - std::sscanf(line.c_str(), "f %d %d %d", &face.first, - &face.second, &face.third); - } - - _faces.push_back(face); - } + _file.open(filename, std::ios::binary); + if (!_file.is_open()) { + throw std::runtime_error("Error opening file"); + } + + std::string line; + while (std::getline(_file, line)) { + if (line.substr(0, 2) == "v ") { + Vec3 vertex; + std::sscanf(line.c_str(), "v %f %f %f", &vertex.x, &vertex.y, &vertex.z); + _vertices.push_back(vertex); + } else if (line.substr(0, 2) == "f ") { + Face face; + if (line.find(std::string("//")) != std::string::npos) { + std::sscanf(line.c_str(), "f %d//%*d %d//%*d %d//%*d", &face.first, &face.second, + &face.third); + } else if (line.find(std::string("/")) != std::string::npos) { + std::sscanf(line.c_str(), "f %d/%*d/%*d %d/%*d/%*d %d/%*d/%*d", &face.first, &face.second, + &face.third); + } else { + std::sscanf(line.c_str(), "f %d %d %d", &face.first, &face.second, &face.third); + } + + _faces.push_back(face); } + } } void Model::Scale(int scale) { - Vec3 min; - Vec3 max; - min.x = min.y = min.z = std::numeric_limits::max(); - max.x = max.y = max.z = std::numeric_limits::lowest(); - - for (const Vec3& vertex : _vertices) { - min.x = std::min(min.x, vertex.x); - min.y = std::min(min.y, vertex.y); - min.z = std::min(min.z, vertex.z); - - max.x = std::max(max.x, vertex.x); - max.y = std::max(max.y, vertex.y); - max.z = std::max(max.z, vertex.z); - } - - float size = - std::max(max.x - min.x, std::max(max.y - min.y, max.z - min.z)); - for (Vec3& vertex : _vertices) { - vertex.x = (vertex.x - min.x) / size * scale; - vertex.y = (vertex.y - min.y) / size * scale; - vertex.z = (vertex.z - min.z) / size * scale; - } + Vec3 min; + Vec3 max; + min.x = min.y = min.z = std::numeric_limits::max(); + max.x = max.y = max.z = std::numeric_limits::lowest(); + + for (const Vec3& vertex : _vertices) { + min.x = std::min(min.x, vertex.x); + min.y = std::min(min.y, vertex.y); + min.z = std::min(min.z, vertex.z); + + max.x = std::max(max.x, vertex.x); + max.y = std::max(max.y, vertex.y); + max.z = std::max(max.z, vertex.z); + } + + float size = std::max(max.x - min.x, std::max(max.y - min.y, max.z - min.z)); + for (Vec3& vertex : _vertices) { + vertex.x = (vertex.x - min.x) / size * scale; + vertex.y = (vertex.y - min.y) / size * scale; + vertex.z = (vertex.z - min.z) / size * scale; + } } void Model::BuildPointCloud(mcpp::MinecraftConnection& mc) { - for (const Vec3& vertex : _vertices) { - mcpp::Coordinate blockPosition = - mcpp::Coordinate(_position.x + vertex.x, _position.y + vertex.y, - _position.z + vertex.z); - mc.setBlock(blockPosition, mcpp::Blocks::GRAY_WOOL); - } + for (const Vec3& vertex : _vertices) { + mcpp::Coordinate blockPosition = + mcpp::Coordinate(_position.x + vertex.x, _position.y + vertex.y, _position.z + vertex.z); + mc.setBlock(blockPosition, mcpp::Blocks::GRAY_WOOL); + } } void Model::BuildModel(mcpp::MinecraftConnection& mc) { - Vec3 min; - Vec3 max; - min.x = min.y = min.z = std::numeric_limits::max(); - max.x = max.y = max.z = std::numeric_limits::lowest(); - - for (const Vec3& vertex : _vertices) { - min.x = std::min(min.x, vertex.x); - min.y = std::min(min.y, vertex.y); - min.z = std::min(min.z, vertex.z); - - max.x = std::max(max.x, vertex.x); - max.y = std::max(max.y, vertex.y); - max.z = std::max(max.z, vertex.z); - } - - for (int x = min.x; x < max.x; x++) { - for (int y = min.y; y < max.y; y++) { - for (int z = min.z; z < max.z; z++) { - Vec3 position = {(float)x, (float)y, (float)z}; - if (IsWithin(position)) { - mcpp::Coordinate blockPosition = mcpp::Coordinate( - _position.x + x, _position.y + y, _position.z + z); - mc.setBlock(blockPosition, mcpp::Blocks::GRAY_CONCRETE); - } - } + Vec3 min; + Vec3 max; + min.x = min.y = min.z = std::numeric_limits::max(); + max.x = max.y = max.z = std::numeric_limits::lowest(); + + for (const Vec3& vertex : _vertices) { + min.x = std::min(min.x, vertex.x); + min.y = std::min(min.y, vertex.y); + min.z = std::min(min.z, vertex.z); + + max.x = std::max(max.x, vertex.x); + max.y = std::max(max.y, vertex.y); + max.z = std::max(max.z, vertex.z); + } + + for (int x = min.x; x < max.x; x++) { + for (int y = min.y; y < max.y; y++) { + for (int z = min.z; z < max.z; z++) { + Vec3 position = {(float)x, (float)y, (float)z}; + if (IsWithin(position)) { + mcpp::Coordinate blockPosition = + mcpp::Coordinate(_position.x + x, _position.y + y, _position.z + z); + mc.setBlock(blockPosition, mcpp::Blocks::GRAY_CONCRETE); } + } } + } } bool Model::IsWithin(Vec3& position) { - const float EpsilonFloat = 0.0000001; - const Vec3 directions[4] = { - {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}}; - - int crosses = 0; + const float EpsilonFloat = 0.0000001; + const Vec3 directions[4] = {{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}}; - for (Vec3 direction : directions) { - int intersects = 0; + int crosses = 0; - for (const Face& face : _faces) { - // 1 based indexing -.- - Vec3 v1 = _vertices[face.first - 1]; - Vec3 v2 = _vertices[face.second - 1]; - Vec3 v3 = _vertices[face.third - 1]; + for (Vec3 direction : directions) { + int intersects = 0; - Vec3 edge1 = sub(v2, v1); - Vec3 edge2 = sub(v3, v1); + for (const Face& face : _faces) { + // 1 based indexing -.- + Vec3 v1 = _vertices[face.first - 1]; + Vec3 v2 = _vertices[face.second - 1]; + Vec3 v3 = _vertices[face.third - 1]; - Vec3 h = cross(direction, edge2); - float det = dot(edge1, h); + Vec3 edge1 = sub(v2, v1); + Vec3 edge2 = sub(v3, v1); - if (std::abs(det) < EpsilonFloat) - continue; // parallel + Vec3 h = cross(direction, edge2); + float det = dot(edge1, h); - float f = 1.0 / det; - Vec3 s = sub(position, v1); - float u = f * dot(s, h); + if (std::abs(det) < EpsilonFloat) + continue; // parallel - if (u < 0.0 || u > 1.0) - continue; // outside face + float f = 1.0 / det; + Vec3 s = sub(position, v1); + float u = f * dot(s, h); - Vec3 q = cross(s, edge1); - float v = f * dot(direction, q); + if (u < 0.0 || u > 1.0) + continue; // outside face - if (v < 0.0 || u + v > 1.0) - continue; // outside face + Vec3 q = cross(s, edge1); + float v = f * dot(direction, q); - float t = f * dot(edge2, q); + if (v < 0.0 || u + v > 1.0) + continue; // outside face - if (t > EpsilonFloat) - intersects++; - } + float t = f * dot(edge2, q); - if (intersects % 2 == 1) - crosses++; + if (t > EpsilonFloat) + intersects++; } - return (crosses >= 2); -} + if (intersects % 2 == 1) + crosses++; + } -Vec3 Model::sub(Vec3 a, Vec3 b) { - return Vec3{a.x - b.x, a.y - b.y, a.z - b.z}; + return (crosses >= 2); } + +Vec3 Model::sub(Vec3 a, Vec3 b) { return Vec3{a.x - b.x, a.y - b.y, a.z - b.z}; } float Model::dot(Vec3 a, Vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } Vec3 Model::cross(Vec3 a, Vec3 b) { - return Vec3{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, - a.x * b.y - a.y * b.x}; + return Vec3{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } void Model::SetPosition(mcpp::Coordinate position) { - _position = position; - _position.x += 16; - _position.z += 16; -}; \ No newline at end of file + _position = position; + _position.x += 16; + _position.z += 16; +}; diff --git a/example/pyramid.cpp b/example/pyramid.cpp index 56ce0a7..78d61c0 100644 --- a/example/pyramid.cpp +++ b/example/pyramid.cpp @@ -1,7 +1,5 @@ #include -#include #include -#include // Change location here mcpp::Coordinate ORIGIN{0, 0, 0}; @@ -11,32 +9,29 @@ int PYRAMID_HEIGHT = 50; mcpp::MinecraftConnection mc; void make_ring(mcpp::Coordinate base_pt, int side_len) { - // Flat plane - mc.setBlocks(base_pt, base_pt + mcpp::Coordinate(side_len, 0, side_len), - mcpp::Blocks::SANDSTONE); - - // Air inside to make border - base_pt = base_pt + mcpp::Coordinate(1, 0, 1); - mc.setBlocks(base_pt, - base_pt + mcpp::Coordinate(side_len - 2, 0, side_len - 2), - mcpp::Blocks::AIR); + // Flat plane + mc.setBlocks(base_pt, base_pt + mcpp::Coordinate(side_len, 0, side_len), mcpp::Blocks::SANDSTONE); + + // Air inside to make border + base_pt = base_pt + mcpp::Coordinate(1, 0, 1); + mc.setBlocks(base_pt, base_pt + mcpp::Coordinate(side_len - 2, 0, side_len - 2), + mcpp::Blocks::AIR); } int main() { - int pyramid_base_len = PYRAMID_HEIGHT * 2; - - // Get heights of build area - mcpp::HeightMap heights = - mc.getHeights(ORIGIN, ORIGIN + mcpp::Coordinate(pyramid_base_len, 0, - pyramid_base_len)); - - // Use minimum height of the area as the lowest point on the pyramid - int min_height = *std::min_element(heights.begin(), heights.end()); - - // Build rings, diminishing up to pyramid height - mcpp::Coordinate base_pt = heights.base_pt().with_height(min_height); - int side_len = pyramid_base_len; - for (int i = 0; i < PYRAMID_HEIGHT; i++) { - make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2)); - } + int pyramid_base_len = PYRAMID_HEIGHT * 2; + + // Get heights of build area + mcpp::HeightMap heights = + mc.getHeights(ORIGIN, ORIGIN + mcpp::Coordinate(pyramid_base_len, 0, pyramid_base_len)); + + // Use minimum height of the area as the lowest point on the pyramid + int min_height = *std::min_element(heights.begin(), heights.end()); + + // Build rings, diminishing up to pyramid height + mcpp::Coordinate base_pt = heights.base_pt().with_height(min_height); + int side_len = pyramid_base_len; + for (int i = 0; i < PYRAMID_HEIGHT; i++) { + make_ring(base_pt + mcpp::Coordinate(i, i, i), side_len - (i * 2)); + } } diff --git a/example/video-generation/video-mc.cpp b/example/video-generation/video-mc.cpp index 91a4fc8..822b5c0 100644 --- a/example/video-generation/video-mc.cpp +++ b/example/video-generation/video-mc.cpp @@ -8,227 +8,220 @@ #include struct Pixel { - uint8_t r, g, b; + uint8_t r, g, b; }; class Video { - public: - Video(const std::string& filename, int width, int height, int scaleFactor, - int frameRate); - ~Video() { - if (_file.is_open()) { - _file.close(); - } +public: + Video(const std::string& filename, int width, int height, int scaleFactor, int frameRate); + ~Video() { + if (_file.is_open()) { + _file.close(); } + } - void Play(mcpp::MinecraftConnection& mc); + void Play(mcpp::MinecraftConnection& mc); - private: - void DisplayFrame(size_t index, mcpp::MinecraftConnection& mc); - mcpp::BlockType GetBestBlock(const Pixel& pixel); +private: + void DisplayFrame(size_t index, mcpp::MinecraftConnection& mc); + mcpp::BlockType GetBestBlock(const Pixel& pixel); - std::ifstream _file; - std::vector> _frames; + std::ifstream _file; + std::vector> _frames; - int _width; - int _height; - int _scaleFactor; - int _frameRate; - int _frameDelay; - int _frameSize; + int _width; + int _height; + int _scaleFactor; + int _frameRate; + int _frameDelay; + int _frameSize; - mcpp::Coordinate _position; - std::vector _options; - std::vector _optionColors; + mcpp::Coordinate _position; + std::vector _options; + std::vector _optionColors; }; int main(int argc, char* argv[]) { - if (argc < 6) { - std::cerr << "Usage: " << argv[0] - << " filename.rgb width height scale frame_rate" << std::endl; - return 1; - } - - std::string filename = argv[1]; - if (filename.find(".mp4") != std::string::npos) { - std::cerr << "Be sure to convert mp4 files to rgb files before use." - << std::endl - << "Usage: ffmpeg -i filename.mp4 -f rawvideo -pix_fmt rgb24 " - "filename.rgb" - << std::endl; - return 1; - } - - int width = std::stoi(argv[2]); - int height = std::stoi(argv[3]); - int scaleFactor = std::stoi(argv[4]); - int frameRate = std::stoi(argv[5]); - - mcpp::MinecraftConnection mc; - - Video* video = new Video(filename, width, height, scaleFactor, frameRate); - video->Play(mc); - - return 0; + if (argc < 6) { + std::cerr << "Usage: " << argv[0] << " filename.rgb width height scale frame_rate" << std::endl; + return 1; + } + + std::string filename = argv[1]; + if (filename.find(".mp4") != std::string::npos) { + std::cerr << "Be sure to convert mp4 files to rgb files before use." << std::endl + << "Usage: ffmpeg -i filename.mp4 -f rawvideo -pix_fmt rgb24 " + "filename.rgb" + << std::endl; + return 1; + } + + int width = std::stoi(argv[2]); + int height = std::stoi(argv[3]); + int scaleFactor = std::stoi(argv[4]); + int frameRate = std::stoi(argv[5]); + + mcpp::MinecraftConnection mc; + + Video* video = new Video(filename, width, height, scaleFactor, frameRate); + video->Play(mc); + + return 0; } -Video::Video(const std::string& filename, int width, int height, - int scaleFactor, int frameRate) - : _width(width), _height(height), _scaleFactor(scaleFactor), - _frameRate(frameRate), _frameDelay(1000 / _frameRate), - _frameSize(_width * _height * 3) { - _file.open(filename, std::ios::binary); - if (!_file.is_open()) { - throw std::runtime_error("Error opening file"); - } - - while (_file) { - std::vector frame; - frame.resize(_width * _height); - _file.read(reinterpret_cast(frame.data()), _frameSize); - - if (_file.gcount() == _frameSize) { - _frames.push_back(frame); - } else { - break; - } +Video::Video(const std::string& filename, int width, int height, int scaleFactor, int frameRate) + : _width(width), _height(height), _scaleFactor(scaleFactor), _frameRate(frameRate), + _frameDelay(1000 / _frameRate), _frameSize(_width * _height * 3) { + _file.open(filename, std::ios::binary); + if (!_file.is_open()) { + throw std::runtime_error("Error opening file"); + } + + while (_file) { + std::vector frame; + frame.resize(_width * _height); + _file.read(reinterpret_cast(frame.data()), _frameSize); + + if (_file.gcount() == _frameSize) { + _frames.push_back(frame); + } else { + break; } + } } void Video::Play(mcpp::MinecraftConnection& mc) { - _options.push_back(mcpp::Blocks::RED_CONCRETE); - _options.push_back(mcpp::Blocks::BLUE_CONCRETE); - _options.push_back(mcpp::Blocks::CYAN_CONCRETE); - _options.push_back(mcpp::Blocks::GRAY_CONCRETE); - _options.push_back(mcpp::Blocks::LIME_CONCRETE); - _options.push_back(mcpp::Blocks::PINK_CONCRETE); - _options.push_back(mcpp::Blocks::BLACK_CONCRETE); - _options.push_back(mcpp::Blocks::BROWN_CONCRETE); - _options.push_back(mcpp::Blocks::GREEN_CONCRETE); - _options.push_back(mcpp::Blocks::WHITE_CONCRETE); - _options.push_back(mcpp::Blocks::ORANGE_CONCRETE); - _options.push_back(mcpp::Blocks::PURPLE_CONCRETE); - _options.push_back(mcpp::Blocks::YELLOW_CONCRETE); - _options.push_back(mcpp::Blocks::MAGENTA_CONCRETE); - _options.push_back(mcpp::Blocks::LIGHT_BLUE_CONCRETE); - _options.push_back(mcpp::Blocks::LIGHT_GRAY_CONCRETE); - - _options.push_back(mcpp::Blocks::RED_WOOL); - _options.push_back(mcpp::Blocks::BLUE_WOOL); - _options.push_back(mcpp::Blocks::CYAN_WOOL); - _options.push_back(mcpp::Blocks::GRAY_WOOL); - _options.push_back(mcpp::Blocks::LIME_WOOL); - _options.push_back(mcpp::Blocks::PINK_WOOL); - _options.push_back(mcpp::Blocks::BLACK_WOOL); - _options.push_back(mcpp::Blocks::BROWN_WOOL); - _options.push_back(mcpp::Blocks::GREEN_WOOL); - _options.push_back(mcpp::Blocks::WHITE_WOOL); - _options.push_back(mcpp::Blocks::ORANGE_WOOL); - _options.push_back(mcpp::Blocks::PURPLE_WOOL); - _options.push_back(mcpp::Blocks::YELLOW_WOOL); - _options.push_back(mcpp::Blocks::MAGENTA_WOOL); - _options.push_back(mcpp::Blocks::LIGHT_BLUE_WOOL); - _options.push_back(mcpp::Blocks::LIGHT_GRAY_WOOL); - - _optionColors.push_back(Pixel{142, 33, 33}); // RED CONCRETE - _optionColors.push_back(Pixel{45, 47, 143}); // BLUE CONCRETE - _optionColors.push_back(Pixel{21, 119, 136}); // CYAN CONCRETE - _optionColors.push_back(Pixel{55, 58, 62}); // GRAY CONCRETE - _optionColors.push_back(Pixel{94, 169, 24}); // LIME CONCRETE - _optionColors.push_back(Pixel{213, 101, 143}); // PINK CONCRETE - _optionColors.push_back(Pixel{8, 10, 15}); // BLACK CONCRETE - _optionColors.push_back(Pixel{96, 60, 32}); // BROWN CONCRETE - _optionColors.push_back(Pixel{73, 91, 36}); // GREEN CONCRETE - _optionColors.push_back(Pixel{255, 255, 255}); // WHITE CONCRETE - _optionColors.push_back(Pixel{224, 97, 1}); // ORANGE CONCRETE - _optionColors.push_back(Pixel{100, 32, 156}); // PURPLE CONCRETE - _optionColors.push_back(Pixel{241, 175, 21}); // YELLOW CONCRETE - _optionColors.push_back(Pixel{169, 48, 159}); // MAGENTA CONCRETE - _optionColors.push_back(Pixel{36, 137, 199}); // LIGHT BLUE CONCRETE - _optionColors.push_back(Pixel{125, 125, 115}); // LIGHT GRAY CONCRETE - - _optionColors.push_back(Pixel{158, 43, 39}); // RED WOOL - _optionColors.push_back(Pixel{37, 49, 147}); // BLUE WOOL - _optionColors.push_back(Pixel{38, 113, 145}); // CYAN WOOL - _optionColors.push_back(Pixel{65, 65, 65}); // GRAY WOOL - _optionColors.push_back(Pixel{57, 186, 46}); // LIME WOOL - _optionColors.push_back(Pixel{217, 129, 153}); // PINK WOOL - _optionColors.push_back(Pixel{24, 20, 20}); // BLACK WOOL - _optionColors.push_back(Pixel{86, 51, 28}); // BROWN WOOL - _optionColors.push_back(Pixel{54, 75, 24}); // GREEN WOOL - _optionColors.push_back(Pixel{228, 228, 228}); // WHITE WOOL - _optionColors.push_back(Pixel{235, 126, 54}); // ORANGE WOOL - _optionColors.push_back(Pixel{126, 52, 191}); // PURPLE WOOL - _optionColors.push_back(Pixel{194, 181, 28}); // YELLOW WOOL - _optionColors.push_back(Pixel{190, 73, 201}); // MAGENTA WOOL - _optionColors.push_back(Pixel{228, 236, 253}); // LIGHT BLUE WOOL - _optionColors.push_back(Pixel{160, 167, 167}); // LIGHT GRAY WOOL - - _position = mc.getPlayerPosition(); - _position.y += (_height / _scaleFactor) / 2; - _position.z -= - std::max((_width / _scaleFactor) / 2, (_height / _scaleFactor) / 2); - _position.x += std::min((_width / _scaleFactor) / 2, 16); - - for (size_t i = 0; i < _frames.size(); i++) { - DisplayFrame(i, mc); - std::this_thread::sleep_for(std::chrono::milliseconds(_frameDelay)); - } + _options.push_back(mcpp::Blocks::RED_CONCRETE); + _options.push_back(mcpp::Blocks::BLUE_CONCRETE); + _options.push_back(mcpp::Blocks::CYAN_CONCRETE); + _options.push_back(mcpp::Blocks::GRAY_CONCRETE); + _options.push_back(mcpp::Blocks::LIME_CONCRETE); + _options.push_back(mcpp::Blocks::PINK_CONCRETE); + _options.push_back(mcpp::Blocks::BLACK_CONCRETE); + _options.push_back(mcpp::Blocks::BROWN_CONCRETE); + _options.push_back(mcpp::Blocks::GREEN_CONCRETE); + _options.push_back(mcpp::Blocks::WHITE_CONCRETE); + _options.push_back(mcpp::Blocks::ORANGE_CONCRETE); + _options.push_back(mcpp::Blocks::PURPLE_CONCRETE); + _options.push_back(mcpp::Blocks::YELLOW_CONCRETE); + _options.push_back(mcpp::Blocks::MAGENTA_CONCRETE); + _options.push_back(mcpp::Blocks::LIGHT_BLUE_CONCRETE); + _options.push_back(mcpp::Blocks::LIGHT_GRAY_CONCRETE); + + _options.push_back(mcpp::Blocks::RED_WOOL); + _options.push_back(mcpp::Blocks::BLUE_WOOL); + _options.push_back(mcpp::Blocks::CYAN_WOOL); + _options.push_back(mcpp::Blocks::GRAY_WOOL); + _options.push_back(mcpp::Blocks::LIME_WOOL); + _options.push_back(mcpp::Blocks::PINK_WOOL); + _options.push_back(mcpp::Blocks::BLACK_WOOL); + _options.push_back(mcpp::Blocks::BROWN_WOOL); + _options.push_back(mcpp::Blocks::GREEN_WOOL); + _options.push_back(mcpp::Blocks::WHITE_WOOL); + _options.push_back(mcpp::Blocks::ORANGE_WOOL); + _options.push_back(mcpp::Blocks::PURPLE_WOOL); + _options.push_back(mcpp::Blocks::YELLOW_WOOL); + _options.push_back(mcpp::Blocks::MAGENTA_WOOL); + _options.push_back(mcpp::Blocks::LIGHT_BLUE_WOOL); + _options.push_back(mcpp::Blocks::LIGHT_GRAY_WOOL); + + _optionColors.push_back(Pixel{142, 33, 33}); // RED CONCRETE + _optionColors.push_back(Pixel{45, 47, 143}); // BLUE CONCRETE + _optionColors.push_back(Pixel{21, 119, 136}); // CYAN CONCRETE + _optionColors.push_back(Pixel{55, 58, 62}); // GRAY CONCRETE + _optionColors.push_back(Pixel{94, 169, 24}); // LIME CONCRETE + _optionColors.push_back(Pixel{213, 101, 143}); // PINK CONCRETE + _optionColors.push_back(Pixel{8, 10, 15}); // BLACK CONCRETE + _optionColors.push_back(Pixel{96, 60, 32}); // BROWN CONCRETE + _optionColors.push_back(Pixel{73, 91, 36}); // GREEN CONCRETE + _optionColors.push_back(Pixel{255, 255, 255}); // WHITE CONCRETE + _optionColors.push_back(Pixel{224, 97, 1}); // ORANGE CONCRETE + _optionColors.push_back(Pixel{100, 32, 156}); // PURPLE CONCRETE + _optionColors.push_back(Pixel{241, 175, 21}); // YELLOW CONCRETE + _optionColors.push_back(Pixel{169, 48, 159}); // MAGENTA CONCRETE + _optionColors.push_back(Pixel{36, 137, 199}); // LIGHT BLUE CONCRETE + _optionColors.push_back(Pixel{125, 125, 115}); // LIGHT GRAY CONCRETE + + _optionColors.push_back(Pixel{158, 43, 39}); // RED WOOL + _optionColors.push_back(Pixel{37, 49, 147}); // BLUE WOOL + _optionColors.push_back(Pixel{38, 113, 145}); // CYAN WOOL + _optionColors.push_back(Pixel{65, 65, 65}); // GRAY WOOL + _optionColors.push_back(Pixel{57, 186, 46}); // LIME WOOL + _optionColors.push_back(Pixel{217, 129, 153}); // PINK WOOL + _optionColors.push_back(Pixel{24, 20, 20}); // BLACK WOOL + _optionColors.push_back(Pixel{86, 51, 28}); // BROWN WOOL + _optionColors.push_back(Pixel{54, 75, 24}); // GREEN WOOL + _optionColors.push_back(Pixel{228, 228, 228}); // WHITE WOOL + _optionColors.push_back(Pixel{235, 126, 54}); // ORANGE WOOL + _optionColors.push_back(Pixel{126, 52, 191}); // PURPLE WOOL + _optionColors.push_back(Pixel{194, 181, 28}); // YELLOW WOOL + _optionColors.push_back(Pixel{190, 73, 201}); // MAGENTA WOOL + _optionColors.push_back(Pixel{228, 236, 253}); // LIGHT BLUE WOOL + _optionColors.push_back(Pixel{160, 167, 167}); // LIGHT GRAY WOOL + + _position = mc.getPlayerPosition(); + _position.y += (_height / _scaleFactor) / 2; + _position.z -= std::max((_width / _scaleFactor) / 2, (_height / _scaleFactor) / 2); + _position.x += std::min((_width / _scaleFactor) / 2, 16); + + for (size_t i = 0; i < _frames.size(); i++) { + DisplayFrame(i, mc); + std::this_thread::sleep_for(std::chrono::milliseconds(_frameDelay)); + } } void Video::DisplayFrame(size_t index, mcpp::MinecraftConnection& mc) { - if (index < _frames.size()) { - const std::vector& frame = _frames[index]; - - if (!frame.empty()) { - for (size_t i = 0; i < frame.size(); i += _scaleFactor) { - const Pixel& pixel = frame[i]; - if (index > 0) { - const Pixel& lastPixel = _frames[index - 1][i]; - if (pixel.r == lastPixel.r && pixel.g == lastPixel.g && - pixel.b == lastPixel.b) { - continue; - } - } - - mcpp::BlockType blockType = GetBestBlock(pixel); - - mcpp::Coordinate pixelPosition = mcpp::Coordinate(_position); - pixelPosition.z += (i % _width) / _scaleFactor; - pixelPosition.y -= (i / _width) / _scaleFactor; - - mc.setBlock(pixelPosition, blockType); - } + if (index < _frames.size()) { + const std::vector& frame = _frames[index]; + + if (!frame.empty()) { + for (size_t i = 0; i < frame.size(); i += _scaleFactor) { + const Pixel& pixel = frame[i]; + if (index > 0) { + const Pixel& lastPixel = _frames[index - 1][i]; + if (pixel.r == lastPixel.r && pixel.g == lastPixel.g && pixel.b == lastPixel.b) { + continue; + } } + + mcpp::BlockType blockType = GetBestBlock(pixel); + + mcpp::Coordinate pixelPosition = mcpp::Coordinate(_position); + pixelPosition.z += (i % _width) / _scaleFactor; + pixelPosition.y -= (i / _width) / _scaleFactor; + + mc.setBlock(pixelPosition, blockType); + } } + } } mcpp::BlockType Video::GetBestBlock(const Pixel& pixel) { - int r = pixel.r; - int g = pixel.g; - int b = pixel.b; + int r = pixel.r; + int g = pixel.g; + int b = pixel.b; - int minDistance = 256; - int closestOption = -1; + int minDistance = 256; + int closestOption = -1; - for (size_t i = 0; i < _optionColors.size(); i++) { - int dr = std::abs(r - _optionColors[i].r); - int dg = std::abs(g - _optionColors[i].g); - int db = std::abs(b - _optionColors[i].b); + for (size_t i = 0; i < _optionColors.size(); i++) { + int dr = std::abs(r - _optionColors[i].r); + int dg = std::abs(g - _optionColors[i].g); + int db = std::abs(b - _optionColors[i].b); - int distance = std::sqrt(dr * dr + dg * dg + db * db); + int distance = std::sqrt(dr * dr + dg * dg + db * db); - if (distance < minDistance) { - minDistance = distance; - closestOption = i; - } + if (distance < minDistance) { + minDistance = distance; + closestOption = i; } + } - if (closestOption != -1) { - return _options[closestOption]; - } else { - std::cerr << "Color error" << std::endl; - } + if (closestOption != -1) { + return _options[closestOption]; + } else { + std::cerr << "Color error" << std::endl; + } - return mcpp::Blocks::GLASS; // fallback; shouldn't happen + return mcpp::Blocks::GLASS; // fallback; shouldn't happen } diff --git a/include/mcpp/block.h b/include/mcpp/block.h index 1e3ac36..27693ce 100644 --- a/include/mcpp/block.h +++ b/include/mcpp/block.h @@ -8,56 +8,56 @@ */ namespace mcpp { class BlockType { - public: - int id; - int mod; +public: + int id; + int mod; - constexpr BlockType(int id = 0, int modifier = 0) : id(id), mod(modifier){}; + constexpr BlockType(int id = 0, int modifier = 0) : id(id), mod(modifier) {}; - /** - * @brief Equality comparison operator. - * - * Watch out as this also compares the BlockType.mod element of the block, - * so some equalities may behave in unexpected ways e.g. rotated stairs - * - * @param other The BlockType to compare with the current instance. - * - * @return True if the two BlockType instances are not equal, false - * otherwise. - */ - bool operator==(const BlockType& other) const; + /** + * @brief Equality comparison operator. + * + * Watch out as this also compares the BlockType.mod element of the block, + * so some equalities may behave in unexpected ways e.g. rotated stairs + * + * @param other The BlockType to compare with the current instance. + * + * @return True if the two BlockType instances are not equal, false + * otherwise. + */ + bool operator==(const BlockType& other) const; - /** - * @brief Inequality comparison operator. - * - * Watch out as this also compares the BlockType.mod element of the block, - * so some equalities may behave in unexpected ways e.g. rotated stairs - * - * @param other The BlockType to compare with the current instance. - * @return True if the two BlockType instances are not equal, false - * otherwise. - */ - bool operator!=(const BlockType& other) const; + /** + * @brief Inequality comparison operator. + * + * Watch out as this also compares the BlockType.mod element of the block, + * so some equalities may behave in unexpected ways e.g. rotated stairs + * + * @param other The BlockType to compare with the current instance. + * @return True if the two BlockType instances are not equal, false + * otherwise. + */ + bool operator!=(const BlockType& other) const; - /** - * @brief Stream insertion operator for outputting the BlockType to an - * output stream. - * - * @param out The output stream to write to. - * @param block The BlockType instance to output. - * @return A reference to the output stream after the block information has - * been inserted. - */ - friend std::ostream& operator<<(std::ostream& out, const BlockType& block); + /** + * @brief Stream insertion operator for outputting the BlockType to an + * output stream. + * + * @param out The output stream to write to. + * @param block The BlockType instance to output. + * @return A reference to the output stream after the block information has + * been inserted. + */ + friend std::ostream& operator<<(std::ostream& out, const BlockType& block); - /** - * Returns a new BlockType with the same id and specified modifier, useful - * for rotations etc. - * - * @param modifier New modifier for the BlockType - * @return New BlockType object with the specified modifier - */ - [[nodiscard]] BlockType withMod(int modifier) const; + /** + * Returns a new BlockType with the same id and specified modifier, useful + * for rotations etc. + * + * @param modifier New modifier for the BlockType + * @return New BlockType object with the specified modifier + */ + [[nodiscard]] BlockType withMod(int modifier) const; }; // Using script to extract ids from https://minecraft-ids.grahamedgecombe.com/ @@ -68,451 +68,447 @@ class BlockType { * using Blocks::TYPE after importing */ struct Blocks { - static constexpr BlockType AIR = BlockType(0); - static constexpr BlockType STONE = BlockType(1); - static constexpr BlockType GRANITE = BlockType(1, 1); - static constexpr BlockType POLISHED_GRANITE = BlockType(1, 2); - static constexpr BlockType DIORITE = BlockType(1, 3); - static constexpr BlockType POLISHED_DIORITE = BlockType(1, 4); - static constexpr BlockType ANDESITE = BlockType(1, 5); - static constexpr BlockType POLISHED_ANDESITE = BlockType(1, 6); - static constexpr BlockType GRASS = BlockType(2); - static constexpr BlockType DIRT = BlockType(3); - static constexpr BlockType COARSE_DIRT = BlockType(3, 1); - static constexpr BlockType PODZOL = BlockType(3, 2); - static constexpr BlockType COBBLESTONE = BlockType(4); - static constexpr BlockType OAK_WOOD_PLANK = BlockType(5); - static constexpr BlockType SPRUCE_WOOD_PLANK = BlockType(5, 1); - static constexpr BlockType BIRCH_WOOD_PLANK = BlockType(5, 2); - static constexpr BlockType JUNGLE_WOOD_PLANK = BlockType(5, 3); - static constexpr BlockType ACACIA_WOOD_PLANK = BlockType(5, 4); - static constexpr BlockType DARK_OAK_WOOD_PLANK = BlockType(5, 5); - static constexpr BlockType OAK_SAPLING = BlockType(6); - static constexpr BlockType SPRUCE_SAPLING = BlockType(6, 1); - static constexpr BlockType BIRCH_SAPLING = BlockType(6, 2); - static constexpr BlockType JUNGLE_SAPLING = BlockType(6, 3); - static constexpr BlockType ACACIA_SAPLING = BlockType(6, 4); - static constexpr BlockType DARK_OAK_SAPLING = BlockType(6, 5); - static constexpr BlockType BEDROCK = BlockType(7); - static constexpr BlockType FLOWING_WATER = BlockType(8); - static constexpr BlockType STILL_WATER = BlockType(9); - static constexpr BlockType FLOWING_LAVA = BlockType(10); - static constexpr BlockType STILL_LAVA = BlockType(11); - static constexpr BlockType SAND = BlockType(12); - static constexpr BlockType RED_SAND = BlockType(12, 1); - static constexpr BlockType GRAVEL = BlockType(13); - static constexpr BlockType GOLD_ORE = BlockType(14); - static constexpr BlockType IRON_ORE = BlockType(15); - static constexpr BlockType COAL_ORE = BlockType(16); - static constexpr BlockType OAK_WOOD = BlockType(17); - static constexpr BlockType SPRUCE_WOOD = BlockType(17, 1); - static constexpr BlockType BIRCH_WOOD = BlockType(17, 2); - static constexpr BlockType JUNGLE_WOOD = BlockType(17, 3); - static constexpr BlockType OAK_LEAVES = BlockType(18); - static constexpr BlockType SPRUCE_LEAVES = BlockType(18, 1); - static constexpr BlockType BIRCH_LEAVES = BlockType(18, 2); - static constexpr BlockType JUNGLE_LEAVES = BlockType(18, 3); - static constexpr BlockType SPONGE = BlockType(19); - static constexpr BlockType WET_SPONGE = BlockType(19, 1); - static constexpr BlockType GLASS = BlockType(20); - static constexpr BlockType LAPIS_LAZULI_ORE = BlockType(21); - static constexpr BlockType LAPIS_LAZULI_BLOCK = BlockType(22); - static constexpr BlockType DISPENSER = BlockType(23); - static constexpr BlockType SANDSTONE = BlockType(24); - static constexpr BlockType CHISELED_SANDSTONE = BlockType(24, 1); - static constexpr BlockType SMOOTH_SANDSTONE = BlockType(24, 2); - static constexpr BlockType NOTE_BLOCK = BlockType(25); - static constexpr BlockType BED = BlockType(26); - static constexpr BlockType POWERED_RAIL = BlockType(27); - static constexpr BlockType DETECTOR_RAIL = BlockType(28); - static constexpr BlockType STICKY_PISTON = BlockType(29); - static constexpr BlockType COBWEB = BlockType(30); - static constexpr BlockType DEAD_SHRUB = BlockType(31); - static constexpr BlockType TALL_GRASS = BlockType(31, 1); - static constexpr BlockType FERN = BlockType(31, 2); - static constexpr BlockType DEAD_BUSH = BlockType(32); - static constexpr BlockType PISTON = BlockType(33); - static constexpr BlockType PISTON_HEAD = BlockType(34); - static constexpr BlockType WHITE_WOOL = BlockType(35); - static constexpr BlockType ORANGE_WOOL = BlockType(35, 1); - static constexpr BlockType MAGENTA_WOOL = BlockType(35, 2); - static constexpr BlockType LIGHT_BLUE_WOOL = BlockType(35, 3); - static constexpr BlockType YELLOW_WOOL = BlockType(35, 4); - static constexpr BlockType LIME_WOOL = BlockType(35, 5); - static constexpr BlockType PINK_WOOL = BlockType(35, 6); - static constexpr BlockType GRAY_WOOL = BlockType(35, 7); - static constexpr BlockType LIGHT_GRAY_WOOL = BlockType(35, 8); - static constexpr BlockType CYAN_WOOL = BlockType(35, 9); - static constexpr BlockType PURPLE_WOOL = BlockType(35, 10); - static constexpr BlockType BLUE_WOOL = BlockType(35, 11); - static constexpr BlockType BROWN_WOOL = BlockType(35, 12); - static constexpr BlockType GREEN_WOOL = BlockType(35, 13); - static constexpr BlockType RED_WOOL = BlockType(35, 14); - static constexpr BlockType BLACK_WOOL = BlockType(35, 15); - static constexpr BlockType DANDELION = BlockType(37); - static constexpr BlockType POPPY = BlockType(38); - static constexpr BlockType BLUE_ORCHID = BlockType(38, 1); - static constexpr BlockType ALLIUM = BlockType(38, 2); - static constexpr BlockType AZURE_BLUET = BlockType(38, 3); - static constexpr BlockType RED_TULIP = BlockType(38, 4); - static constexpr BlockType ORANGE_TULIP = BlockType(38, 5); - static constexpr BlockType WHITE_TULIP = BlockType(38, 6); - static constexpr BlockType PINK_TULIP = BlockType(38, 7); - static constexpr BlockType OXEYE_DAISY = BlockType(38, 8); - static constexpr BlockType BROWN_MUSHROOM = BlockType(39); - static constexpr BlockType RED_MUSHROOM = BlockType(40); - static constexpr BlockType GOLD_BLOCK = BlockType(41); - static constexpr BlockType IRON_BLOCK = BlockType(42); - static constexpr BlockType DOUBLE_STONE_SLAB = BlockType(43); - static constexpr BlockType DOUBLE_SANDSTONE_SLAB = BlockType(43, 1); - static constexpr BlockType DOUBLE_WOODEN_SLAB = BlockType(43, 2); - static constexpr BlockType DOUBLE_COBBLESTONE_SLAB = BlockType(43, 3); - static constexpr BlockType DOUBLE_BRICK_SLAB = BlockType(43, 4); - static constexpr BlockType DOUBLE_STONE_BRICK_SLAB = BlockType(43, 5); - static constexpr BlockType DOUBLE_NETHER_BRICK_SLAB = BlockType(43, 6); - static constexpr BlockType DOUBLE_QUARTZ_SLAB = BlockType(43, 7); - static constexpr BlockType STONE_SLAB = BlockType(44); - static constexpr BlockType SANDSTONE_SLAB = BlockType(44, 1); - static constexpr BlockType WOODEN_SLAB = BlockType(44, 2); - static constexpr BlockType COBBLESTONE_SLAB = BlockType(44, 3); - static constexpr BlockType BRICK_SLAB = BlockType(44, 4); - static constexpr BlockType STONE_BRICK_SLAB = BlockType(44, 5); - static constexpr BlockType NETHER_BRICK_SLAB = BlockType(44, 6); - static constexpr BlockType QUARTZ_SLAB = BlockType(44, 7); - static constexpr BlockType BRICKS = BlockType(45); - static constexpr BlockType TNT = BlockType(46); - static constexpr BlockType BOOKSHELF = BlockType(47); - static constexpr BlockType MOSS_STONE = BlockType(48); - static constexpr BlockType OBSIDIAN = BlockType(49); - static constexpr BlockType TORCH = BlockType(50); - static constexpr BlockType FIRE = BlockType(51); - static constexpr BlockType MONSTER_SPAWNER = BlockType(52); - static constexpr BlockType OAK_WOOD_STAIRS = BlockType(53); - static constexpr BlockType CHEST = BlockType(54); - static constexpr BlockType REDSTONE_WIRE = BlockType(55); - static constexpr BlockType DIAMOND_ORE = BlockType(56); - static constexpr BlockType DIAMOND_BLOCK = BlockType(57); - static constexpr BlockType CRAFTING_TABLE = BlockType(58); - static constexpr BlockType WHEAT_CROPS = BlockType(59); - static constexpr BlockType FARMLAND = BlockType(60); - static constexpr BlockType FURNACE = BlockType(61); - static constexpr BlockType BURNING_FURNACE = BlockType(62); - static constexpr BlockType STANDING_SIGN_BLOCK = BlockType(63); - static constexpr BlockType OAK_DOOR_BLOCK = BlockType(64); - static constexpr BlockType LADDER = BlockType(65); - static constexpr BlockType RAIL = BlockType(66); - static constexpr BlockType COBBLESTONE_STAIRS = BlockType(67); - static constexpr BlockType WALLMOUNTED_SIGN_BLOCK = BlockType(68); - static constexpr BlockType LEVER = BlockType(69); - static constexpr BlockType STONE_PRESSURE_PLATE = BlockType(70); - static constexpr BlockType IRON_DOOR_BLOCK = BlockType(71); - static constexpr BlockType WOODEN_PRESSURE_PLATE = BlockType(72); - static constexpr BlockType REDSTONE_ORE = BlockType(73); - static constexpr BlockType GLOWING_REDSTONE_ORE = BlockType(74); - static constexpr BlockType REDSTONE_TORCH_OFF = BlockType(75); - static constexpr BlockType REDSTONE_TORCH_ON = BlockType(76); - static constexpr BlockType STONE_BUTTON = BlockType(77); - static constexpr BlockType SNOW = BlockType(78); - static constexpr BlockType ICE = BlockType(79); - static constexpr BlockType SNOW_BLOCK = BlockType(80); - static constexpr BlockType CACTUS = BlockType(81); - static constexpr BlockType CLAY = BlockType(82); - static constexpr BlockType SUGAR_CANES = BlockType(83); - static constexpr BlockType JUKEBOX = BlockType(84); - static constexpr BlockType OAK_FENCE = BlockType(85); - static constexpr BlockType PUMPKIN = BlockType(86); - static constexpr BlockType NETHERRACK = BlockType(87); - static constexpr BlockType SOUL_SAND = BlockType(88); - static constexpr BlockType GLOWSTONE = BlockType(89); - static constexpr BlockType NETHER_PORTAL = BlockType(90); - static constexpr BlockType JACK_OLANTERN = BlockType(91); - static constexpr BlockType CAKE_BLOCK = BlockType(92); - static constexpr BlockType REDSTONE_REPEATER_BLOCK_OFF = BlockType(93); - static constexpr BlockType REDSTONE_REPEATER_BLOCK_ON = BlockType(94); - static constexpr BlockType WHITE_STAINED_GLASS = BlockType(95); - static constexpr BlockType ORANGE_STAINED_GLASS = BlockType(95, 1); - static constexpr BlockType MAGENTA_STAINED_GLASS = BlockType(95, 2); - static constexpr BlockType LIGHT_BLUE_STAINED_GLASS = BlockType(95, 3); - static constexpr BlockType YELLOW_STAINED_GLASS = BlockType(95, 4); - static constexpr BlockType LIME_STAINED_GLASS = BlockType(95, 5); - static constexpr BlockType PINK_STAINED_GLASS = BlockType(95, 6); - static constexpr BlockType GRAY_STAINED_GLASS = BlockType(95, 7); - static constexpr BlockType LIGHT_GRAY_STAINED_GLASS = BlockType(95, 8); - static constexpr BlockType CYAN_STAINED_GLASS = BlockType(95, 9); - static constexpr BlockType PURPLE_STAINED_GLASS = BlockType(95, 10); - static constexpr BlockType BLUE_STAINED_GLASS = BlockType(95, 11); - static constexpr BlockType BROWN_STAINED_GLASS = BlockType(95, 12); - static constexpr BlockType GREEN_STAINED_GLASS = BlockType(95, 13); - static constexpr BlockType RED_STAINED_GLASS = BlockType(95, 14); - static constexpr BlockType BLACK_STAINED_GLASS = BlockType(95, 15); - static constexpr BlockType WOODEN_TRAPDOOR = BlockType(96); - static constexpr BlockType STONE_MONSTER_EGG = BlockType(97); - static constexpr BlockType COBBLESTONE_MONSTER_EGG = BlockType(97, 1); - static constexpr BlockType STONE_BRICK_MONSTER_EGG = BlockType(97, 2); - static constexpr BlockType MOSSY_STONE_BRICK_MONSTER_EGG = BlockType(97, 3); - static constexpr BlockType CRACKED_STONE_BRICK_MONSTER_EGG = - BlockType(97, 4); - static constexpr BlockType CHISELED_STONE_BRICK_MONSTER_EGG = - BlockType(97, 5); - static constexpr BlockType STONE_BRICKS = BlockType(98); - static constexpr BlockType MOSSY_STONE_BRICKS = BlockType(98, 1); - static constexpr BlockType CRACKED_STONE_BRICKS = BlockType(98, 2); - static constexpr BlockType CHISELED_STONE_BRICKS = BlockType(98, 3); - static constexpr BlockType BROWN_MUSHROOM_BLOCK = BlockType(99); - static constexpr BlockType RED_MUSHROOM_BLOCK = BlockType(100); - static constexpr BlockType IRON_BARS = BlockType(101); - static constexpr BlockType GLASS_PANE = BlockType(102); - static constexpr BlockType MELON_BLOCK = BlockType(103); - static constexpr BlockType PUMPKIN_STEM = BlockType(104); - static constexpr BlockType MELON_STEM = BlockType(105); - static constexpr BlockType VINES = BlockType(106); - static constexpr BlockType OAK_FENCE_GATE = BlockType(107); - static constexpr BlockType BRICK_STAIRS = BlockType(108); - static constexpr BlockType STONE_BRICK_STAIRS = BlockType(109); - static constexpr BlockType MYCELIUM = BlockType(110); - static constexpr BlockType LILY_PAD = BlockType(111); - static constexpr BlockType NETHER_BRICK = BlockType(112); - static constexpr BlockType NETHER_BRICK_FENCE = BlockType(113); - static constexpr BlockType NETHER_BRICK_STAIRS = BlockType(114); - static constexpr BlockType NETHER_WART = BlockType(115); - static constexpr BlockType ENCHANTMENT_TABLE = BlockType(116); - static constexpr BlockType BREWING_STAND = BlockType(117); - static constexpr BlockType CAULDRON = BlockType(118); - static constexpr BlockType END_PORTAL = BlockType(119); - static constexpr BlockType END_PORTAL_FRAME = BlockType(120); - static constexpr BlockType END_STONE = BlockType(121); - static constexpr BlockType DRAGON_EGG = BlockType(122); - static constexpr BlockType REDSTONE_LAMP_INACTIVE = BlockType(123); - static constexpr BlockType REDSTONE_LAMP_ACTIVE = BlockType(124); - static constexpr BlockType DOUBLE_OAK_WOOD_SLAB = BlockType(125); - static constexpr BlockType DOUBLE_SPRUCE_WOOD_SLAB = BlockType(125, 1); - static constexpr BlockType DOUBLE_BIRCH_WOOD_SLAB = BlockType(125, 2); - static constexpr BlockType DOUBLE_JUNGLE_WOOD_SLAB = BlockType(125, 3); - static constexpr BlockType DOUBLE_ACACIA_WOOD_SLAB = BlockType(125, 4); - static constexpr BlockType DOUBLE_DARK_OAK_WOOD_SLAB = BlockType(125, 5); - static constexpr BlockType OAK_WOOD_SLAB = BlockType(126); - static constexpr BlockType SPRUCE_WOOD_SLAB = BlockType(126, 1); - static constexpr BlockType BIRCH_WOOD_SLAB = BlockType(126, 2); - static constexpr BlockType JUNGLE_WOOD_SLAB = BlockType(126, 3); - static constexpr BlockType ACACIA_WOOD_SLAB = BlockType(126, 4); - static constexpr BlockType DARK_OAK_WOOD_SLAB = BlockType(126, 5); - static constexpr BlockType COCOA = BlockType(127); - static constexpr BlockType SANDSTONE_STAIRS = BlockType(128); - static constexpr BlockType EMERALD_ORE = BlockType(129); - static constexpr BlockType ENDER_CHEST = BlockType(130); - static constexpr BlockType TRIPWIRE_HOOK = BlockType(131); - static constexpr BlockType TRIPWIRE = BlockType(132); - static constexpr BlockType EMERALD_BLOCK = BlockType(133); - static constexpr BlockType SPRUCE_WOOD_STAIRS = BlockType(134); - static constexpr BlockType BIRCH_WOOD_STAIRS = BlockType(135); - static constexpr BlockType JUNGLE_WOOD_STAIRS = BlockType(136); - static constexpr BlockType COMMAND_BLOCK = BlockType(137); - static constexpr BlockType BEACON = BlockType(138); - static constexpr BlockType COBBLESTONE_WALL = BlockType(139); - static constexpr BlockType MOSSY_COBBLESTONE_WALL = BlockType(139, 1); - static constexpr BlockType FLOWER_POT = BlockType(140); - static constexpr BlockType CARROTS = BlockType(141); - static constexpr BlockType POTATOES = BlockType(142); - static constexpr BlockType WOODEN_BUTTON = BlockType(143); - static constexpr BlockType MOB_HEAD = BlockType(144); - static constexpr BlockType ANVIL = BlockType(145); - static constexpr BlockType TRAPPED_CHEST = BlockType(146); - static constexpr BlockType WEIGHTED_PRESSURE_PLATE_LIGHT = BlockType(147); - static constexpr BlockType WEIGHTED_PRESSURE_PLATE_HEAVY = BlockType(148); - static constexpr BlockType REDSTONE_COMPARATOR_INACTIVE = BlockType(149); - static constexpr BlockType REDSTONE_COMPARATOR_ACTIVE = BlockType(150); - static constexpr BlockType DAYLIGHT_SENSOR = BlockType(151); - static constexpr BlockType REDSTONE_BLOCK = BlockType(152); - static constexpr BlockType NETHER_QUARTZ_ORE = BlockType(153); - static constexpr BlockType HOPPER = BlockType(154); - static constexpr BlockType QUARTZ_BLOCK = BlockType(155); - static constexpr BlockType CHISELED_QUARTZ_BLOCK = BlockType(155, 1); - static constexpr BlockType PILLAR_QUARTZ_BLOCK = BlockType(155, 2); - static constexpr BlockType QUARTZ_STAIRS = BlockType(156); - static constexpr BlockType ACTIVATOR_RAIL = BlockType(157); - static constexpr BlockType DROPPER = BlockType(158); - static constexpr BlockType WHITE_HARDENED_CLAY = BlockType(159); - static constexpr BlockType ORANGE_HARDENED_CLAY = BlockType(159, 1); - static constexpr BlockType MAGENTA_HARDENED_CLAY = BlockType(159, 2); - static constexpr BlockType LIGHT_BLUE_HARDENED_CLAY = BlockType(159, 3); - static constexpr BlockType YELLOW_HARDENED_CLAY = BlockType(159, 4); - static constexpr BlockType LIME_HARDENED_CLAY = BlockType(159, 5); - static constexpr BlockType PINK_HARDENED_CLAY = BlockType(159, 6); - static constexpr BlockType GRAY_HARDENED_CLAY = BlockType(159, 7); - static constexpr BlockType LIGHT_GRAY_HARDENED_CLAY = BlockType(159, 8); - static constexpr BlockType CYAN_HARDENED_CLAY = BlockType(159, 9); - static constexpr BlockType PURPLE_HARDENED_CLAY = BlockType(159, 10); - static constexpr BlockType BLUE_HARDENED_CLAY = BlockType(159, 11); - static constexpr BlockType BROWN_HARDENED_CLAY = BlockType(159, 12); - static constexpr BlockType GREEN_HARDENED_CLAY = BlockType(159, 13); - static constexpr BlockType RED_HARDENED_CLAY = BlockType(159, 14); - static constexpr BlockType BLACK_HARDENED_CLAY = BlockType(159, 15); - static constexpr BlockType WHITE_STAINED_GLASS_PANE = BlockType(160); - static constexpr BlockType ORANGE_STAINED_GLASS_PANE = BlockType(160, 1); - static constexpr BlockType MAGENTA_STAINED_GLASS_PANE = BlockType(160, 2); - static constexpr BlockType LIGHT_BLUE_STAINED_GLASS_PANE = - BlockType(160, 3); - static constexpr BlockType YELLOW_STAINED_GLASS_PANE = BlockType(160, 4); - static constexpr BlockType LIME_STAINED_GLASS_PANE = BlockType(160, 5); - static constexpr BlockType PINK_STAINED_GLASS_PANE = BlockType(160, 6); - static constexpr BlockType GRAY_STAINED_GLASS_PANE = BlockType(160, 7); - static constexpr BlockType LIGHT_GRAY_STAINED_GLASS_PANE = - BlockType(160, 8); - static constexpr BlockType CYAN_STAINED_GLASS_PANE = BlockType(160, 9); - static constexpr BlockType PURPLE_STAINED_GLASS_PANE = BlockType(160, 10); - static constexpr BlockType BLUE_STAINED_GLASS_PANE = BlockType(160, 11); - static constexpr BlockType BROWN_STAINED_GLASS_PANE = BlockType(160, 12); - static constexpr BlockType GREEN_STAINED_GLASS_PANE = BlockType(160, 13); - static constexpr BlockType RED_STAINED_GLASS_PANE = BlockType(160, 14); - static constexpr BlockType BLACK_STAINED_GLASS_PANE = BlockType(160, 15); - static constexpr BlockType ACACIA_LEAVES = BlockType(161); - static constexpr BlockType DARK_OAK_LEAVES = BlockType(161, 1); - static constexpr BlockType ACACIA_WOOD = BlockType(162); - static constexpr BlockType DARK_OAK_WOOD = BlockType(162, 1); - static constexpr BlockType ACACIA_WOOD_STAIRS = BlockType(163); - static constexpr BlockType DARK_OAK_WOOD_STAIRS = BlockType(164); - static constexpr BlockType SLIME_BLOCK = BlockType(165); - static constexpr BlockType BARRIER = BlockType(166); - static constexpr BlockType IRON_TRAPDOOR = BlockType(167); - static constexpr BlockType PRISMARINE = BlockType(168); - static constexpr BlockType PRISMARINE_BRICKS = BlockType(168, 1); - static constexpr BlockType DARK_PRISMARINE = BlockType(168, 2); - static constexpr BlockType SEA_LANTERN = BlockType(169); - static constexpr BlockType HAY_BALE = BlockType(170); - static constexpr BlockType WHITE_CARPET = BlockType(171); - static constexpr BlockType ORANGE_CARPET = BlockType(171, 1); - static constexpr BlockType MAGENTA_CARPET = BlockType(171, 2); - static constexpr BlockType LIGHT_BLUE_CARPET = BlockType(171, 3); - static constexpr BlockType YELLOW_CARPET = BlockType(171, 4); - static constexpr BlockType LIME_CARPET = BlockType(171, 5); - static constexpr BlockType PINK_CARPET = BlockType(171, 6); - static constexpr BlockType GRAY_CARPET = BlockType(171, 7); - static constexpr BlockType LIGHT_GRAY_CARPET = BlockType(171, 8); - static constexpr BlockType CYAN_CARPET = BlockType(171, 9); - static constexpr BlockType PURPLE_CARPET = BlockType(171, 10); - static constexpr BlockType BLUE_CARPET = BlockType(171, 11); - static constexpr BlockType BROWN_CARPET = BlockType(171, 12); - static constexpr BlockType GREEN_CARPET = BlockType(171, 13); - static constexpr BlockType RED_CARPET = BlockType(171, 14); - static constexpr BlockType BLACK_CARPET = BlockType(171, 15); - static constexpr BlockType HARDENED_CLAY = BlockType(172); - static constexpr BlockType BLOCK_OF_COAL = BlockType(173); - static constexpr BlockType PACKED_ICE = BlockType(174); - static constexpr BlockType SUNFLOWER = BlockType(175); - static constexpr BlockType LILAC = BlockType(175, 1); - static constexpr BlockType DOUBLE_TALLGRASS = BlockType(175, 2); - static constexpr BlockType LARGE_FERN = BlockType(175, 3); - static constexpr BlockType ROSE_BUSH = BlockType(175, 4); - static constexpr BlockType PEONY = BlockType(175, 5); - static constexpr BlockType FREESTANDING_BANNER = BlockType(176); - static constexpr BlockType WALLMOUNTED_BANNER = BlockType(177); - static constexpr BlockType INVERTED_DAYLIGHT_SENSOR = BlockType(178); - static constexpr BlockType RED_SANDSTONE = BlockType(179); - static constexpr BlockType CHISELED_RED_SANDSTONE = BlockType(179, 1); - static constexpr BlockType SMOOTH_RED_SANDSTONE = BlockType(179, 2); - static constexpr BlockType RED_SANDSTONE_STAIRS = BlockType(180); - static constexpr BlockType DOUBLE_RED_SANDSTONE_SLAB = BlockType(181); - static constexpr BlockType RED_SANDSTONE_SLAB = BlockType(182); - static constexpr BlockType SPRUCE_FENCE_GATE = BlockType(183); - static constexpr BlockType BIRCH_FENCE_GATE = BlockType(184); - static constexpr BlockType JUNGLE_FENCE_GATE = BlockType(185); - static constexpr BlockType DARK_OAK_FENCE_GATE = BlockType(186); - static constexpr BlockType ACACIA_FENCE_GATE = BlockType(187); - static constexpr BlockType SPRUCE_FENCE = BlockType(188); - static constexpr BlockType BIRCH_FENCE = BlockType(189); - static constexpr BlockType JUNGLE_FENCE = BlockType(190); - static constexpr BlockType DARK_OAK_FENCE = BlockType(191); - static constexpr BlockType ACACIA_FENCE = BlockType(192); - static constexpr BlockType SPRUCE_DOOR_BLOCK = BlockType(193); - static constexpr BlockType BIRCH_DOOR_BLOCK = BlockType(194); - static constexpr BlockType JUNGLE_DOOR_BLOCK = BlockType(195); - static constexpr BlockType ACACIA_DOOR_BLOCK = BlockType(196); - static constexpr BlockType DARK_OAK_DOOR_BLOCK = BlockType(197); - static constexpr BlockType END_ROD = BlockType(198); - static constexpr BlockType CHORUS_PLANT = BlockType(199); - static constexpr BlockType CHORUS_FLOWER = BlockType(200); - static constexpr BlockType PURPUR_BLOCK = BlockType(201); - static constexpr BlockType PURPUR_PILLAR = BlockType(202); - static constexpr BlockType PURPUR_STAIRS = BlockType(203); - static constexpr BlockType PURPUR_DOUBLE_SLAB = BlockType(204); - static constexpr BlockType PURPUR_SLAB = BlockType(205); - static constexpr BlockType END_STONE_BRICKS = BlockType(206); - static constexpr BlockType BEETROOT_BLOCK = BlockType(207); - static constexpr BlockType GRASS_PATH = BlockType(208); - static constexpr BlockType END_GATEWAY = BlockType(209); - static constexpr BlockType REPEATING_COMMAND_BLOCK = BlockType(210); - static constexpr BlockType CHAIN_COMMAND_BLOCK = BlockType(211); - static constexpr BlockType FROSTED_ICE = BlockType(212); - static constexpr BlockType MAGMA_BLOCK = BlockType(213); - static constexpr BlockType NETHER_WART_BLOCK = BlockType(214); - static constexpr BlockType RED_NETHER_BRICK = BlockType(215); - static constexpr BlockType BONE_BLOCK = BlockType(216); - static constexpr BlockType STRUCTURE_VOID = BlockType(217); - static constexpr BlockType OBSERVER = BlockType(218); - static constexpr BlockType WHITE_SHULKER_BOX = BlockType(219); - static constexpr BlockType ORANGE_SHULKER_BOX = BlockType(220); - static constexpr BlockType MAGENTA_SHULKER_BOX = BlockType(221); - static constexpr BlockType LIGHT_BLUE_SHULKER_BOX = BlockType(222); - static constexpr BlockType YELLOW_SHULKER_BOX = BlockType(223); - static constexpr BlockType LIME_SHULKER_BOX = BlockType(224); - static constexpr BlockType PINK_SHULKER_BOX = BlockType(225); - static constexpr BlockType GRAY_SHULKER_BOX = BlockType(226); - static constexpr BlockType LIGHT_GRAY_SHULKER_BOX = BlockType(227); - static constexpr BlockType CYAN_SHULKER_BOX = BlockType(228); - static constexpr BlockType PURPLE_SHULKER_BOX = BlockType(229); - static constexpr BlockType BLUE_SHULKER_BOX = BlockType(230); - static constexpr BlockType BROWN_SHULKER_BOX = BlockType(231); - static constexpr BlockType GREEN_SHULKER_BOX = BlockType(232); - static constexpr BlockType RED_SHULKER_BOX = BlockType(233); - static constexpr BlockType BLACK_SHULKER_BOX = BlockType(234); - static constexpr BlockType WHITE_GLAZED_TERRACOTTA = BlockType(235); - static constexpr BlockType ORANGE_GLAZED_TERRACOTTA = BlockType(236); - static constexpr BlockType MAGENTA_GLAZED_TERRACOTTA = BlockType(237); - static constexpr BlockType LIGHT_BLUE_GLAZED_TERRACOTTA = BlockType(238); - static constexpr BlockType YELLOW_GLAZED_TERRACOTTA = BlockType(239); - static constexpr BlockType LIME_GLAZED_TERRACOTTA = BlockType(240); - static constexpr BlockType PINK_GLAZED_TERRACOTTA = BlockType(241); - static constexpr BlockType GRAY_GLAZED_TERRACOTTA = BlockType(242); - static constexpr BlockType LIGHT_GRAY_GLAZED_TERRACOTTA = BlockType(243); - static constexpr BlockType CYAN_GLAZED_TERRACOTTA = BlockType(244); - static constexpr BlockType PURPLE_GLAZED_TERRACOTTA = BlockType(245); - static constexpr BlockType BLUE_GLAZED_TERRACOTTA = BlockType(246); - static constexpr BlockType BROWN_GLAZED_TERRACOTTA = BlockType(247); - static constexpr BlockType GREEN_GLAZED_TERRACOTTA = BlockType(248); - static constexpr BlockType RED_GLAZED_TERRACOTTA = BlockType(249); - static constexpr BlockType BLACK_GLAZED_TERRACOTTA = BlockType(250); - static constexpr BlockType WHITE_CONCRETE = BlockType(251); - static constexpr BlockType ORANGE_CONCRETE = BlockType(251, 1); - static constexpr BlockType MAGENTA_CONCRETE = BlockType(251, 2); - static constexpr BlockType LIGHT_BLUE_CONCRETE = BlockType(251, 3); - static constexpr BlockType YELLOW_CONCRETE = BlockType(251, 4); - static constexpr BlockType LIME_CONCRETE = BlockType(251, 5); - static constexpr BlockType PINK_CONCRETE = BlockType(251, 6); - static constexpr BlockType GRAY_CONCRETE = BlockType(251, 7); - static constexpr BlockType LIGHT_GRAY_CONCRETE = BlockType(251, 8); - static constexpr BlockType CYAN_CONCRETE = BlockType(251, 9); - static constexpr BlockType PURPLE_CONCRETE = BlockType(251, 10); - static constexpr BlockType BLUE_CONCRETE = BlockType(251, 11); - static constexpr BlockType BROWN_CONCRETE = BlockType(251, 12); - static constexpr BlockType GREEN_CONCRETE = BlockType(251, 13); - static constexpr BlockType RED_CONCRETE = BlockType(251, 14); - static constexpr BlockType BLACK_CONCRETE = BlockType(251, 15); - static constexpr BlockType WHITE_CONCRETE_POWDER = BlockType(252); - static constexpr BlockType ORANGE_CONCRETE_POWDER = BlockType(252, 1); - static constexpr BlockType MAGENTA_CONCRETE_POWDER = BlockType(252, 2); - static constexpr BlockType LIGHT_BLUE_CONCRETE_POWDER = BlockType(252, 3); - static constexpr BlockType YELLOW_CONCRETE_POWDER = BlockType(252, 4); - static constexpr BlockType LIME_CONCRETE_POWDER = BlockType(252, 5); - static constexpr BlockType PINK_CONCRETE_POWDER = BlockType(252, 6); - static constexpr BlockType GRAY_CONCRETE_POWDER = BlockType(252, 7); - static constexpr BlockType LIGHT_GRAY_CONCRETE_POWDER = BlockType(252, 8); - static constexpr BlockType CYAN_CONCRETE_POWDER = BlockType(252, 9); - static constexpr BlockType PURPLE_CONCRETE_POWDER = BlockType(252, 10); - static constexpr BlockType BLUE_CONCRETE_POWDER = BlockType(252, 11); - static constexpr BlockType BROWN_CONCRETE_POWDER = BlockType(252, 12); - static constexpr BlockType GREEN_CONCRETE_POWDER = BlockType(252, 13); - static constexpr BlockType RED_CONCRETE_POWDER = BlockType(252, 14); - static constexpr BlockType BLACK_CONCRETE_POWDER = BlockType(252, 15); - static constexpr BlockType STRUCTURE_BLOCK = BlockType(255); + static constexpr BlockType AIR = BlockType(0); + static constexpr BlockType STONE = BlockType(1); + static constexpr BlockType GRANITE = BlockType(1, 1); + static constexpr BlockType POLISHED_GRANITE = BlockType(1, 2); + static constexpr BlockType DIORITE = BlockType(1, 3); + static constexpr BlockType POLISHED_DIORITE = BlockType(1, 4); + static constexpr BlockType ANDESITE = BlockType(1, 5); + static constexpr BlockType POLISHED_ANDESITE = BlockType(1, 6); + static constexpr BlockType GRASS = BlockType(2); + static constexpr BlockType DIRT = BlockType(3); + static constexpr BlockType COARSE_DIRT = BlockType(3, 1); + static constexpr BlockType PODZOL = BlockType(3, 2); + static constexpr BlockType COBBLESTONE = BlockType(4); + static constexpr BlockType OAK_WOOD_PLANK = BlockType(5); + static constexpr BlockType SPRUCE_WOOD_PLANK = BlockType(5, 1); + static constexpr BlockType BIRCH_WOOD_PLANK = BlockType(5, 2); + static constexpr BlockType JUNGLE_WOOD_PLANK = BlockType(5, 3); + static constexpr BlockType ACACIA_WOOD_PLANK = BlockType(5, 4); + static constexpr BlockType DARK_OAK_WOOD_PLANK = BlockType(5, 5); + static constexpr BlockType OAK_SAPLING = BlockType(6); + static constexpr BlockType SPRUCE_SAPLING = BlockType(6, 1); + static constexpr BlockType BIRCH_SAPLING = BlockType(6, 2); + static constexpr BlockType JUNGLE_SAPLING = BlockType(6, 3); + static constexpr BlockType ACACIA_SAPLING = BlockType(6, 4); + static constexpr BlockType DARK_OAK_SAPLING = BlockType(6, 5); + static constexpr BlockType BEDROCK = BlockType(7); + static constexpr BlockType FLOWING_WATER = BlockType(8); + static constexpr BlockType STILL_WATER = BlockType(9); + static constexpr BlockType FLOWING_LAVA = BlockType(10); + static constexpr BlockType STILL_LAVA = BlockType(11); + static constexpr BlockType SAND = BlockType(12); + static constexpr BlockType RED_SAND = BlockType(12, 1); + static constexpr BlockType GRAVEL = BlockType(13); + static constexpr BlockType GOLD_ORE = BlockType(14); + static constexpr BlockType IRON_ORE = BlockType(15); + static constexpr BlockType COAL_ORE = BlockType(16); + static constexpr BlockType OAK_WOOD = BlockType(17); + static constexpr BlockType SPRUCE_WOOD = BlockType(17, 1); + static constexpr BlockType BIRCH_WOOD = BlockType(17, 2); + static constexpr BlockType JUNGLE_WOOD = BlockType(17, 3); + static constexpr BlockType OAK_LEAVES = BlockType(18); + static constexpr BlockType SPRUCE_LEAVES = BlockType(18, 1); + static constexpr BlockType BIRCH_LEAVES = BlockType(18, 2); + static constexpr BlockType JUNGLE_LEAVES = BlockType(18, 3); + static constexpr BlockType SPONGE = BlockType(19); + static constexpr BlockType WET_SPONGE = BlockType(19, 1); + static constexpr BlockType GLASS = BlockType(20); + static constexpr BlockType LAPIS_LAZULI_ORE = BlockType(21); + static constexpr BlockType LAPIS_LAZULI_BLOCK = BlockType(22); + static constexpr BlockType DISPENSER = BlockType(23); + static constexpr BlockType SANDSTONE = BlockType(24); + static constexpr BlockType CHISELED_SANDSTONE = BlockType(24, 1); + static constexpr BlockType SMOOTH_SANDSTONE = BlockType(24, 2); + static constexpr BlockType NOTE_BLOCK = BlockType(25); + static constexpr BlockType BED = BlockType(26); + static constexpr BlockType POWERED_RAIL = BlockType(27); + static constexpr BlockType DETECTOR_RAIL = BlockType(28); + static constexpr BlockType STICKY_PISTON = BlockType(29); + static constexpr BlockType COBWEB = BlockType(30); + static constexpr BlockType DEAD_SHRUB = BlockType(31); + static constexpr BlockType TALL_GRASS = BlockType(31, 1); + static constexpr BlockType FERN = BlockType(31, 2); + static constexpr BlockType DEAD_BUSH = BlockType(32); + static constexpr BlockType PISTON = BlockType(33); + static constexpr BlockType PISTON_HEAD = BlockType(34); + static constexpr BlockType WHITE_WOOL = BlockType(35); + static constexpr BlockType ORANGE_WOOL = BlockType(35, 1); + static constexpr BlockType MAGENTA_WOOL = BlockType(35, 2); + static constexpr BlockType LIGHT_BLUE_WOOL = BlockType(35, 3); + static constexpr BlockType YELLOW_WOOL = BlockType(35, 4); + static constexpr BlockType LIME_WOOL = BlockType(35, 5); + static constexpr BlockType PINK_WOOL = BlockType(35, 6); + static constexpr BlockType GRAY_WOOL = BlockType(35, 7); + static constexpr BlockType LIGHT_GRAY_WOOL = BlockType(35, 8); + static constexpr BlockType CYAN_WOOL = BlockType(35, 9); + static constexpr BlockType PURPLE_WOOL = BlockType(35, 10); + static constexpr BlockType BLUE_WOOL = BlockType(35, 11); + static constexpr BlockType BROWN_WOOL = BlockType(35, 12); + static constexpr BlockType GREEN_WOOL = BlockType(35, 13); + static constexpr BlockType RED_WOOL = BlockType(35, 14); + static constexpr BlockType BLACK_WOOL = BlockType(35, 15); + static constexpr BlockType DANDELION = BlockType(37); + static constexpr BlockType POPPY = BlockType(38); + static constexpr BlockType BLUE_ORCHID = BlockType(38, 1); + static constexpr BlockType ALLIUM = BlockType(38, 2); + static constexpr BlockType AZURE_BLUET = BlockType(38, 3); + static constexpr BlockType RED_TULIP = BlockType(38, 4); + static constexpr BlockType ORANGE_TULIP = BlockType(38, 5); + static constexpr BlockType WHITE_TULIP = BlockType(38, 6); + static constexpr BlockType PINK_TULIP = BlockType(38, 7); + static constexpr BlockType OXEYE_DAISY = BlockType(38, 8); + static constexpr BlockType BROWN_MUSHROOM = BlockType(39); + static constexpr BlockType RED_MUSHROOM = BlockType(40); + static constexpr BlockType GOLD_BLOCK = BlockType(41); + static constexpr BlockType IRON_BLOCK = BlockType(42); + static constexpr BlockType DOUBLE_STONE_SLAB = BlockType(43); + static constexpr BlockType DOUBLE_SANDSTONE_SLAB = BlockType(43, 1); + static constexpr BlockType DOUBLE_WOODEN_SLAB = BlockType(43, 2); + static constexpr BlockType DOUBLE_COBBLESTONE_SLAB = BlockType(43, 3); + static constexpr BlockType DOUBLE_BRICK_SLAB = BlockType(43, 4); + static constexpr BlockType DOUBLE_STONE_BRICK_SLAB = BlockType(43, 5); + static constexpr BlockType DOUBLE_NETHER_BRICK_SLAB = BlockType(43, 6); + static constexpr BlockType DOUBLE_QUARTZ_SLAB = BlockType(43, 7); + static constexpr BlockType STONE_SLAB = BlockType(44); + static constexpr BlockType SANDSTONE_SLAB = BlockType(44, 1); + static constexpr BlockType WOODEN_SLAB = BlockType(44, 2); + static constexpr BlockType COBBLESTONE_SLAB = BlockType(44, 3); + static constexpr BlockType BRICK_SLAB = BlockType(44, 4); + static constexpr BlockType STONE_BRICK_SLAB = BlockType(44, 5); + static constexpr BlockType NETHER_BRICK_SLAB = BlockType(44, 6); + static constexpr BlockType QUARTZ_SLAB = BlockType(44, 7); + static constexpr BlockType BRICKS = BlockType(45); + static constexpr BlockType TNT = BlockType(46); + static constexpr BlockType BOOKSHELF = BlockType(47); + static constexpr BlockType MOSS_STONE = BlockType(48); + static constexpr BlockType OBSIDIAN = BlockType(49); + static constexpr BlockType TORCH = BlockType(50); + static constexpr BlockType FIRE = BlockType(51); + static constexpr BlockType MONSTER_SPAWNER = BlockType(52); + static constexpr BlockType OAK_WOOD_STAIRS = BlockType(53); + static constexpr BlockType CHEST = BlockType(54); + static constexpr BlockType REDSTONE_WIRE = BlockType(55); + static constexpr BlockType DIAMOND_ORE = BlockType(56); + static constexpr BlockType DIAMOND_BLOCK = BlockType(57); + static constexpr BlockType CRAFTING_TABLE = BlockType(58); + static constexpr BlockType WHEAT_CROPS = BlockType(59); + static constexpr BlockType FARMLAND = BlockType(60); + static constexpr BlockType FURNACE = BlockType(61); + static constexpr BlockType BURNING_FURNACE = BlockType(62); + static constexpr BlockType STANDING_SIGN_BLOCK = BlockType(63); + static constexpr BlockType OAK_DOOR_BLOCK = BlockType(64); + static constexpr BlockType LADDER = BlockType(65); + static constexpr BlockType RAIL = BlockType(66); + static constexpr BlockType COBBLESTONE_STAIRS = BlockType(67); + static constexpr BlockType WALLMOUNTED_SIGN_BLOCK = BlockType(68); + static constexpr BlockType LEVER = BlockType(69); + static constexpr BlockType STONE_PRESSURE_PLATE = BlockType(70); + static constexpr BlockType IRON_DOOR_BLOCK = BlockType(71); + static constexpr BlockType WOODEN_PRESSURE_PLATE = BlockType(72); + static constexpr BlockType REDSTONE_ORE = BlockType(73); + static constexpr BlockType GLOWING_REDSTONE_ORE = BlockType(74); + static constexpr BlockType REDSTONE_TORCH_OFF = BlockType(75); + static constexpr BlockType REDSTONE_TORCH_ON = BlockType(76); + static constexpr BlockType STONE_BUTTON = BlockType(77); + static constexpr BlockType SNOW = BlockType(78); + static constexpr BlockType ICE = BlockType(79); + static constexpr BlockType SNOW_BLOCK = BlockType(80); + static constexpr BlockType CACTUS = BlockType(81); + static constexpr BlockType CLAY = BlockType(82); + static constexpr BlockType SUGAR_CANES = BlockType(83); + static constexpr BlockType JUKEBOX = BlockType(84); + static constexpr BlockType OAK_FENCE = BlockType(85); + static constexpr BlockType PUMPKIN = BlockType(86); + static constexpr BlockType NETHERRACK = BlockType(87); + static constexpr BlockType SOUL_SAND = BlockType(88); + static constexpr BlockType GLOWSTONE = BlockType(89); + static constexpr BlockType NETHER_PORTAL = BlockType(90); + static constexpr BlockType JACK_OLANTERN = BlockType(91); + static constexpr BlockType CAKE_BLOCK = BlockType(92); + static constexpr BlockType REDSTONE_REPEATER_BLOCK_OFF = BlockType(93); + static constexpr BlockType REDSTONE_REPEATER_BLOCK_ON = BlockType(94); + static constexpr BlockType WHITE_STAINED_GLASS = BlockType(95); + static constexpr BlockType ORANGE_STAINED_GLASS = BlockType(95, 1); + static constexpr BlockType MAGENTA_STAINED_GLASS = BlockType(95, 2); + static constexpr BlockType LIGHT_BLUE_STAINED_GLASS = BlockType(95, 3); + static constexpr BlockType YELLOW_STAINED_GLASS = BlockType(95, 4); + static constexpr BlockType LIME_STAINED_GLASS = BlockType(95, 5); + static constexpr BlockType PINK_STAINED_GLASS = BlockType(95, 6); + static constexpr BlockType GRAY_STAINED_GLASS = BlockType(95, 7); + static constexpr BlockType LIGHT_GRAY_STAINED_GLASS = BlockType(95, 8); + static constexpr BlockType CYAN_STAINED_GLASS = BlockType(95, 9); + static constexpr BlockType PURPLE_STAINED_GLASS = BlockType(95, 10); + static constexpr BlockType BLUE_STAINED_GLASS = BlockType(95, 11); + static constexpr BlockType BROWN_STAINED_GLASS = BlockType(95, 12); + static constexpr BlockType GREEN_STAINED_GLASS = BlockType(95, 13); + static constexpr BlockType RED_STAINED_GLASS = BlockType(95, 14); + static constexpr BlockType BLACK_STAINED_GLASS = BlockType(95, 15); + static constexpr BlockType WOODEN_TRAPDOOR = BlockType(96); + static constexpr BlockType STONE_MONSTER_EGG = BlockType(97); + static constexpr BlockType COBBLESTONE_MONSTER_EGG = BlockType(97, 1); + static constexpr BlockType STONE_BRICK_MONSTER_EGG = BlockType(97, 2); + static constexpr BlockType MOSSY_STONE_BRICK_MONSTER_EGG = BlockType(97, 3); + static constexpr BlockType CRACKED_STONE_BRICK_MONSTER_EGG = BlockType(97, 4); + static constexpr BlockType CHISELED_STONE_BRICK_MONSTER_EGG = BlockType(97, 5); + static constexpr BlockType STONE_BRICKS = BlockType(98); + static constexpr BlockType MOSSY_STONE_BRICKS = BlockType(98, 1); + static constexpr BlockType CRACKED_STONE_BRICKS = BlockType(98, 2); + static constexpr BlockType CHISELED_STONE_BRICKS = BlockType(98, 3); + static constexpr BlockType BROWN_MUSHROOM_BLOCK = BlockType(99); + static constexpr BlockType RED_MUSHROOM_BLOCK = BlockType(100); + static constexpr BlockType IRON_BARS = BlockType(101); + static constexpr BlockType GLASS_PANE = BlockType(102); + static constexpr BlockType MELON_BLOCK = BlockType(103); + static constexpr BlockType PUMPKIN_STEM = BlockType(104); + static constexpr BlockType MELON_STEM = BlockType(105); + static constexpr BlockType VINES = BlockType(106); + static constexpr BlockType OAK_FENCE_GATE = BlockType(107); + static constexpr BlockType BRICK_STAIRS = BlockType(108); + static constexpr BlockType STONE_BRICK_STAIRS = BlockType(109); + static constexpr BlockType MYCELIUM = BlockType(110); + static constexpr BlockType LILY_PAD = BlockType(111); + static constexpr BlockType NETHER_BRICK = BlockType(112); + static constexpr BlockType NETHER_BRICK_FENCE = BlockType(113); + static constexpr BlockType NETHER_BRICK_STAIRS = BlockType(114); + static constexpr BlockType NETHER_WART = BlockType(115); + static constexpr BlockType ENCHANTMENT_TABLE = BlockType(116); + static constexpr BlockType BREWING_STAND = BlockType(117); + static constexpr BlockType CAULDRON = BlockType(118); + static constexpr BlockType END_PORTAL = BlockType(119); + static constexpr BlockType END_PORTAL_FRAME = BlockType(120); + static constexpr BlockType END_STONE = BlockType(121); + static constexpr BlockType DRAGON_EGG = BlockType(122); + static constexpr BlockType REDSTONE_LAMP_INACTIVE = BlockType(123); + static constexpr BlockType REDSTONE_LAMP_ACTIVE = BlockType(124); + static constexpr BlockType DOUBLE_OAK_WOOD_SLAB = BlockType(125); + static constexpr BlockType DOUBLE_SPRUCE_WOOD_SLAB = BlockType(125, 1); + static constexpr BlockType DOUBLE_BIRCH_WOOD_SLAB = BlockType(125, 2); + static constexpr BlockType DOUBLE_JUNGLE_WOOD_SLAB = BlockType(125, 3); + static constexpr BlockType DOUBLE_ACACIA_WOOD_SLAB = BlockType(125, 4); + static constexpr BlockType DOUBLE_DARK_OAK_WOOD_SLAB = BlockType(125, 5); + static constexpr BlockType OAK_WOOD_SLAB = BlockType(126); + static constexpr BlockType SPRUCE_WOOD_SLAB = BlockType(126, 1); + static constexpr BlockType BIRCH_WOOD_SLAB = BlockType(126, 2); + static constexpr BlockType JUNGLE_WOOD_SLAB = BlockType(126, 3); + static constexpr BlockType ACACIA_WOOD_SLAB = BlockType(126, 4); + static constexpr BlockType DARK_OAK_WOOD_SLAB = BlockType(126, 5); + static constexpr BlockType COCOA = BlockType(127); + static constexpr BlockType SANDSTONE_STAIRS = BlockType(128); + static constexpr BlockType EMERALD_ORE = BlockType(129); + static constexpr BlockType ENDER_CHEST = BlockType(130); + static constexpr BlockType TRIPWIRE_HOOK = BlockType(131); + static constexpr BlockType TRIPWIRE = BlockType(132); + static constexpr BlockType EMERALD_BLOCK = BlockType(133); + static constexpr BlockType SPRUCE_WOOD_STAIRS = BlockType(134); + static constexpr BlockType BIRCH_WOOD_STAIRS = BlockType(135); + static constexpr BlockType JUNGLE_WOOD_STAIRS = BlockType(136); + static constexpr BlockType COMMAND_BLOCK = BlockType(137); + static constexpr BlockType BEACON = BlockType(138); + static constexpr BlockType COBBLESTONE_WALL = BlockType(139); + static constexpr BlockType MOSSY_COBBLESTONE_WALL = BlockType(139, 1); + static constexpr BlockType FLOWER_POT = BlockType(140); + static constexpr BlockType CARROTS = BlockType(141); + static constexpr BlockType POTATOES = BlockType(142); + static constexpr BlockType WOODEN_BUTTON = BlockType(143); + static constexpr BlockType MOB_HEAD = BlockType(144); + static constexpr BlockType ANVIL = BlockType(145); + static constexpr BlockType TRAPPED_CHEST = BlockType(146); + static constexpr BlockType WEIGHTED_PRESSURE_PLATE_LIGHT = BlockType(147); + static constexpr BlockType WEIGHTED_PRESSURE_PLATE_HEAVY = BlockType(148); + static constexpr BlockType REDSTONE_COMPARATOR_INACTIVE = BlockType(149); + static constexpr BlockType REDSTONE_COMPARATOR_ACTIVE = BlockType(150); + static constexpr BlockType DAYLIGHT_SENSOR = BlockType(151); + static constexpr BlockType REDSTONE_BLOCK = BlockType(152); + static constexpr BlockType NETHER_QUARTZ_ORE = BlockType(153); + static constexpr BlockType HOPPER = BlockType(154); + static constexpr BlockType QUARTZ_BLOCK = BlockType(155); + static constexpr BlockType CHISELED_QUARTZ_BLOCK = BlockType(155, 1); + static constexpr BlockType PILLAR_QUARTZ_BLOCK = BlockType(155, 2); + static constexpr BlockType QUARTZ_STAIRS = BlockType(156); + static constexpr BlockType ACTIVATOR_RAIL = BlockType(157); + static constexpr BlockType DROPPER = BlockType(158); + static constexpr BlockType WHITE_HARDENED_CLAY = BlockType(159); + static constexpr BlockType ORANGE_HARDENED_CLAY = BlockType(159, 1); + static constexpr BlockType MAGENTA_HARDENED_CLAY = BlockType(159, 2); + static constexpr BlockType LIGHT_BLUE_HARDENED_CLAY = BlockType(159, 3); + static constexpr BlockType YELLOW_HARDENED_CLAY = BlockType(159, 4); + static constexpr BlockType LIME_HARDENED_CLAY = BlockType(159, 5); + static constexpr BlockType PINK_HARDENED_CLAY = BlockType(159, 6); + static constexpr BlockType GRAY_HARDENED_CLAY = BlockType(159, 7); + static constexpr BlockType LIGHT_GRAY_HARDENED_CLAY = BlockType(159, 8); + static constexpr BlockType CYAN_HARDENED_CLAY = BlockType(159, 9); + static constexpr BlockType PURPLE_HARDENED_CLAY = BlockType(159, 10); + static constexpr BlockType BLUE_HARDENED_CLAY = BlockType(159, 11); + static constexpr BlockType BROWN_HARDENED_CLAY = BlockType(159, 12); + static constexpr BlockType GREEN_HARDENED_CLAY = BlockType(159, 13); + static constexpr BlockType RED_HARDENED_CLAY = BlockType(159, 14); + static constexpr BlockType BLACK_HARDENED_CLAY = BlockType(159, 15); + static constexpr BlockType WHITE_STAINED_GLASS_PANE = BlockType(160); + static constexpr BlockType ORANGE_STAINED_GLASS_PANE = BlockType(160, 1); + static constexpr BlockType MAGENTA_STAINED_GLASS_PANE = BlockType(160, 2); + static constexpr BlockType LIGHT_BLUE_STAINED_GLASS_PANE = BlockType(160, 3); + static constexpr BlockType YELLOW_STAINED_GLASS_PANE = BlockType(160, 4); + static constexpr BlockType LIME_STAINED_GLASS_PANE = BlockType(160, 5); + static constexpr BlockType PINK_STAINED_GLASS_PANE = BlockType(160, 6); + static constexpr BlockType GRAY_STAINED_GLASS_PANE = BlockType(160, 7); + static constexpr BlockType LIGHT_GRAY_STAINED_GLASS_PANE = BlockType(160, 8); + static constexpr BlockType CYAN_STAINED_GLASS_PANE = BlockType(160, 9); + static constexpr BlockType PURPLE_STAINED_GLASS_PANE = BlockType(160, 10); + static constexpr BlockType BLUE_STAINED_GLASS_PANE = BlockType(160, 11); + static constexpr BlockType BROWN_STAINED_GLASS_PANE = BlockType(160, 12); + static constexpr BlockType GREEN_STAINED_GLASS_PANE = BlockType(160, 13); + static constexpr BlockType RED_STAINED_GLASS_PANE = BlockType(160, 14); + static constexpr BlockType BLACK_STAINED_GLASS_PANE = BlockType(160, 15); + static constexpr BlockType ACACIA_LEAVES = BlockType(161); + static constexpr BlockType DARK_OAK_LEAVES = BlockType(161, 1); + static constexpr BlockType ACACIA_WOOD = BlockType(162); + static constexpr BlockType DARK_OAK_WOOD = BlockType(162, 1); + static constexpr BlockType ACACIA_WOOD_STAIRS = BlockType(163); + static constexpr BlockType DARK_OAK_WOOD_STAIRS = BlockType(164); + static constexpr BlockType SLIME_BLOCK = BlockType(165); + static constexpr BlockType BARRIER = BlockType(166); + static constexpr BlockType IRON_TRAPDOOR = BlockType(167); + static constexpr BlockType PRISMARINE = BlockType(168); + static constexpr BlockType PRISMARINE_BRICKS = BlockType(168, 1); + static constexpr BlockType DARK_PRISMARINE = BlockType(168, 2); + static constexpr BlockType SEA_LANTERN = BlockType(169); + static constexpr BlockType HAY_BALE = BlockType(170); + static constexpr BlockType WHITE_CARPET = BlockType(171); + static constexpr BlockType ORANGE_CARPET = BlockType(171, 1); + static constexpr BlockType MAGENTA_CARPET = BlockType(171, 2); + static constexpr BlockType LIGHT_BLUE_CARPET = BlockType(171, 3); + static constexpr BlockType YELLOW_CARPET = BlockType(171, 4); + static constexpr BlockType LIME_CARPET = BlockType(171, 5); + static constexpr BlockType PINK_CARPET = BlockType(171, 6); + static constexpr BlockType GRAY_CARPET = BlockType(171, 7); + static constexpr BlockType LIGHT_GRAY_CARPET = BlockType(171, 8); + static constexpr BlockType CYAN_CARPET = BlockType(171, 9); + static constexpr BlockType PURPLE_CARPET = BlockType(171, 10); + static constexpr BlockType BLUE_CARPET = BlockType(171, 11); + static constexpr BlockType BROWN_CARPET = BlockType(171, 12); + static constexpr BlockType GREEN_CARPET = BlockType(171, 13); + static constexpr BlockType RED_CARPET = BlockType(171, 14); + static constexpr BlockType BLACK_CARPET = BlockType(171, 15); + static constexpr BlockType HARDENED_CLAY = BlockType(172); + static constexpr BlockType BLOCK_OF_COAL = BlockType(173); + static constexpr BlockType PACKED_ICE = BlockType(174); + static constexpr BlockType SUNFLOWER = BlockType(175); + static constexpr BlockType LILAC = BlockType(175, 1); + static constexpr BlockType DOUBLE_TALLGRASS = BlockType(175, 2); + static constexpr BlockType LARGE_FERN = BlockType(175, 3); + static constexpr BlockType ROSE_BUSH = BlockType(175, 4); + static constexpr BlockType PEONY = BlockType(175, 5); + static constexpr BlockType FREESTANDING_BANNER = BlockType(176); + static constexpr BlockType WALLMOUNTED_BANNER = BlockType(177); + static constexpr BlockType INVERTED_DAYLIGHT_SENSOR = BlockType(178); + static constexpr BlockType RED_SANDSTONE = BlockType(179); + static constexpr BlockType CHISELED_RED_SANDSTONE = BlockType(179, 1); + static constexpr BlockType SMOOTH_RED_SANDSTONE = BlockType(179, 2); + static constexpr BlockType RED_SANDSTONE_STAIRS = BlockType(180); + static constexpr BlockType DOUBLE_RED_SANDSTONE_SLAB = BlockType(181); + static constexpr BlockType RED_SANDSTONE_SLAB = BlockType(182); + static constexpr BlockType SPRUCE_FENCE_GATE = BlockType(183); + static constexpr BlockType BIRCH_FENCE_GATE = BlockType(184); + static constexpr BlockType JUNGLE_FENCE_GATE = BlockType(185); + static constexpr BlockType DARK_OAK_FENCE_GATE = BlockType(186); + static constexpr BlockType ACACIA_FENCE_GATE = BlockType(187); + static constexpr BlockType SPRUCE_FENCE = BlockType(188); + static constexpr BlockType BIRCH_FENCE = BlockType(189); + static constexpr BlockType JUNGLE_FENCE = BlockType(190); + static constexpr BlockType DARK_OAK_FENCE = BlockType(191); + static constexpr BlockType ACACIA_FENCE = BlockType(192); + static constexpr BlockType SPRUCE_DOOR_BLOCK = BlockType(193); + static constexpr BlockType BIRCH_DOOR_BLOCK = BlockType(194); + static constexpr BlockType JUNGLE_DOOR_BLOCK = BlockType(195); + static constexpr BlockType ACACIA_DOOR_BLOCK = BlockType(196); + static constexpr BlockType DARK_OAK_DOOR_BLOCK = BlockType(197); + static constexpr BlockType END_ROD = BlockType(198); + static constexpr BlockType CHORUS_PLANT = BlockType(199); + static constexpr BlockType CHORUS_FLOWER = BlockType(200); + static constexpr BlockType PURPUR_BLOCK = BlockType(201); + static constexpr BlockType PURPUR_PILLAR = BlockType(202); + static constexpr BlockType PURPUR_STAIRS = BlockType(203); + static constexpr BlockType PURPUR_DOUBLE_SLAB = BlockType(204); + static constexpr BlockType PURPUR_SLAB = BlockType(205); + static constexpr BlockType END_STONE_BRICKS = BlockType(206); + static constexpr BlockType BEETROOT_BLOCK = BlockType(207); + static constexpr BlockType GRASS_PATH = BlockType(208); + static constexpr BlockType END_GATEWAY = BlockType(209); + static constexpr BlockType REPEATING_COMMAND_BLOCK = BlockType(210); + static constexpr BlockType CHAIN_COMMAND_BLOCK = BlockType(211); + static constexpr BlockType FROSTED_ICE = BlockType(212); + static constexpr BlockType MAGMA_BLOCK = BlockType(213); + static constexpr BlockType NETHER_WART_BLOCK = BlockType(214); + static constexpr BlockType RED_NETHER_BRICK = BlockType(215); + static constexpr BlockType BONE_BLOCK = BlockType(216); + static constexpr BlockType STRUCTURE_VOID = BlockType(217); + static constexpr BlockType OBSERVER = BlockType(218); + static constexpr BlockType WHITE_SHULKER_BOX = BlockType(219); + static constexpr BlockType ORANGE_SHULKER_BOX = BlockType(220); + static constexpr BlockType MAGENTA_SHULKER_BOX = BlockType(221); + static constexpr BlockType LIGHT_BLUE_SHULKER_BOX = BlockType(222); + static constexpr BlockType YELLOW_SHULKER_BOX = BlockType(223); + static constexpr BlockType LIME_SHULKER_BOX = BlockType(224); + static constexpr BlockType PINK_SHULKER_BOX = BlockType(225); + static constexpr BlockType GRAY_SHULKER_BOX = BlockType(226); + static constexpr BlockType LIGHT_GRAY_SHULKER_BOX = BlockType(227); + static constexpr BlockType CYAN_SHULKER_BOX = BlockType(228); + static constexpr BlockType PURPLE_SHULKER_BOX = BlockType(229); + static constexpr BlockType BLUE_SHULKER_BOX = BlockType(230); + static constexpr BlockType BROWN_SHULKER_BOX = BlockType(231); + static constexpr BlockType GREEN_SHULKER_BOX = BlockType(232); + static constexpr BlockType RED_SHULKER_BOX = BlockType(233); + static constexpr BlockType BLACK_SHULKER_BOX = BlockType(234); + static constexpr BlockType WHITE_GLAZED_TERRACOTTA = BlockType(235); + static constexpr BlockType ORANGE_GLAZED_TERRACOTTA = BlockType(236); + static constexpr BlockType MAGENTA_GLAZED_TERRACOTTA = BlockType(237); + static constexpr BlockType LIGHT_BLUE_GLAZED_TERRACOTTA = BlockType(238); + static constexpr BlockType YELLOW_GLAZED_TERRACOTTA = BlockType(239); + static constexpr BlockType LIME_GLAZED_TERRACOTTA = BlockType(240); + static constexpr BlockType PINK_GLAZED_TERRACOTTA = BlockType(241); + static constexpr BlockType GRAY_GLAZED_TERRACOTTA = BlockType(242); + static constexpr BlockType LIGHT_GRAY_GLAZED_TERRACOTTA = BlockType(243); + static constexpr BlockType CYAN_GLAZED_TERRACOTTA = BlockType(244); + static constexpr BlockType PURPLE_GLAZED_TERRACOTTA = BlockType(245); + static constexpr BlockType BLUE_GLAZED_TERRACOTTA = BlockType(246); + static constexpr BlockType BROWN_GLAZED_TERRACOTTA = BlockType(247); + static constexpr BlockType GREEN_GLAZED_TERRACOTTA = BlockType(248); + static constexpr BlockType RED_GLAZED_TERRACOTTA = BlockType(249); + static constexpr BlockType BLACK_GLAZED_TERRACOTTA = BlockType(250); + static constexpr BlockType WHITE_CONCRETE = BlockType(251); + static constexpr BlockType ORANGE_CONCRETE = BlockType(251, 1); + static constexpr BlockType MAGENTA_CONCRETE = BlockType(251, 2); + static constexpr BlockType LIGHT_BLUE_CONCRETE = BlockType(251, 3); + static constexpr BlockType YELLOW_CONCRETE = BlockType(251, 4); + static constexpr BlockType LIME_CONCRETE = BlockType(251, 5); + static constexpr BlockType PINK_CONCRETE = BlockType(251, 6); + static constexpr BlockType GRAY_CONCRETE = BlockType(251, 7); + static constexpr BlockType LIGHT_GRAY_CONCRETE = BlockType(251, 8); + static constexpr BlockType CYAN_CONCRETE = BlockType(251, 9); + static constexpr BlockType PURPLE_CONCRETE = BlockType(251, 10); + static constexpr BlockType BLUE_CONCRETE = BlockType(251, 11); + static constexpr BlockType BROWN_CONCRETE = BlockType(251, 12); + static constexpr BlockType GREEN_CONCRETE = BlockType(251, 13); + static constexpr BlockType RED_CONCRETE = BlockType(251, 14); + static constexpr BlockType BLACK_CONCRETE = BlockType(251, 15); + static constexpr BlockType WHITE_CONCRETE_POWDER = BlockType(252); + static constexpr BlockType ORANGE_CONCRETE_POWDER = BlockType(252, 1); + static constexpr BlockType MAGENTA_CONCRETE_POWDER = BlockType(252, 2); + static constexpr BlockType LIGHT_BLUE_CONCRETE_POWDER = BlockType(252, 3); + static constexpr BlockType YELLOW_CONCRETE_POWDER = BlockType(252, 4); + static constexpr BlockType LIME_CONCRETE_POWDER = BlockType(252, 5); + static constexpr BlockType PINK_CONCRETE_POWDER = BlockType(252, 6); + static constexpr BlockType GRAY_CONCRETE_POWDER = BlockType(252, 7); + static constexpr BlockType LIGHT_GRAY_CONCRETE_POWDER = BlockType(252, 8); + static constexpr BlockType CYAN_CONCRETE_POWDER = BlockType(252, 9); + static constexpr BlockType PURPLE_CONCRETE_POWDER = BlockType(252, 10); + static constexpr BlockType BLUE_CONCRETE_POWDER = BlockType(252, 11); + static constexpr BlockType BROWN_CONCRETE_POWDER = BlockType(252, 12); + static constexpr BlockType GREEN_CONCRETE_POWDER = BlockType(252, 13); + static constexpr BlockType RED_CONCRETE_POWDER = BlockType(252, 14); + static constexpr BlockType BLACK_CONCRETE_POWDER = BlockType(252, 15); + static constexpr BlockType STRUCTURE_BLOCK = BlockType(255); }; } // namespace mcpp From 86a471162b283b25d4f8d48009df07d90115542b Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:28:15 +1000 Subject: [PATCH 14/19] fix: merge issues with `Coordinate2D` --- include/mcpp/coordinate.h | 96 ++++++ include/mcpp/heightmap.h | 7 +- include/mcpp/mcpp.h | 2 +- include/mcpp/util.h | 693 -------------------------------------- src/coordinate.cpp | 44 +++ src/heightmap.cpp | 4 +- src/mcpp.cpp | 2 +- src/util.cpp | 216 ------------ 8 files changed, 148 insertions(+), 916 deletions(-) delete mode 100644 include/mcpp/util.h delete mode 100644 src/util.cpp diff --git a/include/mcpp/coordinate.h b/include/mcpp/coordinate.h index 3bd4917..5711524 100644 --- a/include/mcpp/coordinate.h +++ b/include/mcpp/coordinate.h @@ -7,6 +7,9 @@ * */ namespace mcpp { + +struct Coordinate2D; + /** * Represented using integers since sub-unit coordinates are not of particular * relevance. Allows for operations such as addition between coordinates. @@ -49,6 +52,8 @@ struct Coordinate { */ Coordinate operator+(const Coordinate& obj) const; + Coordinate operator+(const Coordinate2D& obj) const; + /** * @brief Checks if two Coordinate objects are equal. * @@ -93,6 +98,97 @@ struct Coordinate { friend std::ostream& operator<<(std::ostream& out, const Coordinate& coord); }; +/** + * @brief Height-agnostic coordinate class. + * + * Represented using integers since sub-unit coordinates are not of particular + * relevance. Allows for operations such as addition between flat coordinates. + */ +struct Coordinate2D { + /** + * @brief Constructs a Coordinate2D object with integer values. + * + * @param x The x-coordinate. + * @param z The z-coordinate. + */ + constexpr Coordinate2D(int x, int z) : x(x), z(z) {} + + /** + * @brief Constructs a Coordinate2D object with zero values. + */ + constexpr Coordinate2D() : x(0), z(0) {} + + /** + * @brief Constructs a Coordinate2D object with double values. + * + * @param x The x-coordinate as a double. + * @param z The z-coordinate as a double. + */ + constexpr Coordinate2D(double x, double z) : x(static_cast(x)), z(static_cast(z)) {} + + /** + * @brief Constructs a Coordinate2D object from a Coordinate object. + * + * @param coord The Coordinate object. + */ + constexpr Coordinate2D(const Coordinate& coord) : x(coord.x), z(coord.z) {} + + /** + * @brief Constructs a Coordinate object from a Coordinate2D object and a + * y value. + * + * @param coord The Coordinate2D object. + * @param y The y value. + */ + Coordinate with_height(int y) const; + + /** + * @brief Adds two Coordinate2D objects. + * + * @param obj The Coordinate2D object to add. + * @return A new Coordinate2D object representing the sum of the two + * coordinates. + */ + Coordinate2D operator+(const Coordinate2D& obj) const; + + /** + * @brief Checks if two Coordinate2D objects are equal. + * + * @param obj The Coordinate2D object to compare with. + * @return True if the flat coordinates are equal, false otherwise. + */ + bool operator==(const Coordinate2D& obj) const; + + /** + * @brief Checks if two Coordinate2D objects are not equal. + * + * @param obj The Coordinate2D object to compare with. + * @return True if the flat coordinates are not equal, false otherwise. + */ + bool operator!=(const Coordinate2D& obj) const; + + /** + * @brief Subtracts one Coordinate2D object from another. + * + * @param obj The Coordinate2D object to subtract. + * @return A new Coordinate2D object representing the difference between + * the two coordinates. + */ + Coordinate2D operator-(const Coordinate2D& obj) const; + + /** + * @brief Outputs the Coordinate2D object to an ostream. + * + * @param out The output stream. + * @param coord The Coordinate2D object to output. + * @return The output stream with the Coordinate object's values. + */ + friend std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord); + + int x; + int z; +}; + /** * @brief Convert coordinate to string representation. * diff --git a/include/mcpp/heightmap.h b/include/mcpp/heightmap.h index f477cd0..a71d0ad 100644 --- a/include/mcpp/heightmap.h +++ b/include/mcpp/heightmap.h @@ -12,14 +12,15 @@ namespace mcpp { */ struct HeightMap { private: - Coordinate _base_pt; + Coordinate2D _base_pt; uint16_t _x_len; uint16_t _z_len; std::unique_ptr _raw_heights; public: // Constructors and assignment - HeightMap(const Coordinate& loc1, const Coordinate& loc2, const std::vector& heights); + HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, + const std::vector& heights); ~HeightMap() = default; HeightMap(const HeightMap& other) @@ -73,7 +74,7 @@ struct HeightMap { * Gets the minimum coordinate in the HeightMap. * @return the minimum coordinate in the HeightMap. */ - Coordinate base_pt() const; + Coordinate2D base_pt() const; /** * @brief An iterator for the HeightMap structure. diff --git a/include/mcpp/mcpp.h b/include/mcpp/mcpp.h index 7a185ca..7b57ecc 100644 --- a/include/mcpp/mcpp.h +++ b/include/mcpp/mcpp.h @@ -172,7 +172,7 @@ class MinecraftConnection { * @param loc2 2nd corner of rectangle * @return Returns a vector of integers representing the 2D area of heights. */ - [[nodiscard]] HeightMap getHeights(const Coordinate2D& loc1, const Coordinate2D& loc2); + [[nodiscard]] HeightMap getHeights(const Coordinate2D& loc1, const Coordinate2D& loc2) const; // NOLINTEND(readability-identifier-naming) }; diff --git a/include/mcpp/util.h b/include/mcpp/util.h deleted file mode 100644 index d13cda6..0000000 --- a/include/mcpp/util.h +++ /dev/null @@ -1,693 +0,0 @@ -#pragma once - -#include "block.h" -#include -#include -#include -#include - -/** @file - * @brief Coordinate class. - * - */ -namespace mcpp { - -struct Coordinate2D; - -/** - * Represented using integers since sub-unit coordinates are not of particular - * relevance. Allows for operations such as addition between coordinates. - */ -struct Coordinate { - /** - * @brief Constructs a Coordinate object with integer values. - * - * @param x The x-coordinate. - * @param y The y-coordinate. - * @param z The z-coordinate. - */ - constexpr Coordinate(int x, int y, int z) : x(x), y(y), z(z) {} - - /** - * @brief Constructs a Coordinate object with zero values. - */ - constexpr Coordinate() : x(0), y(0), z(0) {} - - /** - * @brief Constructs a Coordinate object with double values. - * - * @param x The x-coordinate as a double. - * @param y The y-coordinate as a double. - * @param z The z-coordinate as a double. - */ - constexpr Coordinate(double x, double y, double z) - : x(static_cast(x)), y(static_cast(y)), - z(static_cast(z)) {} - - /** - * @brief Adds two Coordinate objects. - * - * @param obj The Coordinate object to add. - * @return A new Coordinate object representing the sum of the two - * coordinates. - */ - Coordinate operator+(const Coordinate& obj) const; - - Coordinate operator+(const Coordinate2D& obj) const; - - /** - * @brief Checks if two Coordinate objects are equal. - * - * @param obj The Coordinate object to compare with. - * @return True if the coordinates are equal, false otherwise. - */ - bool operator==(const Coordinate& obj) const; - - /** - * @brief Checks if two Coordinate objects are not equal. - * - * @param obj The Coordinate object to compare with. - * @return True if the coordinates are not equal, false otherwise. - */ - bool operator!=(const Coordinate& obj) const; - - /** - * @brief Subtracts one Coordinate object from another. - * - * @param obj The Coordinate object to subtract. - * @return A new Coordinate object representing the difference between the - * two coordinates. - */ - Coordinate operator-(const Coordinate& obj) const; - - /** - * @brief Creates a copy of the Coordinate object. - * - * @return A new Coordinate object that is a copy of the current object. - */ - [[nodiscard]] Coordinate clone() const; - - /** - * @brief Outputs the Coordinate object to an ostream. - * - * @param out The output stream. - * @param coord The Coordinate object to output. - * @return The output stream with the Coordinate object's values. - */ - friend std::ostream& operator<<(std::ostream& out, const Coordinate& coord); - - int x; - int y; - int z; -}; - -/** - * @brief Height-agnostic coordinate class. - * - * Represented using integers since sub-unit coordinates are not of particular - * relevance. Allows for operations such as addition between flat coordinates. - */ -struct Coordinate2D { - /** - * @brief Constructs a Coordinate2D object with integer values. - * - * @param x The x-coordinate. - * @param z The z-coordinate. - */ - constexpr Coordinate2D(int x, int z) : x(x), z(z) {} - - /** - * @brief Constructs a Coordinate2D object with zero values. - */ - constexpr Coordinate2D() : x(0), z(0) {} - - /** - * @brief Constructs a Coordinate2D object with double values. - * - * @param x The x-coordinate as a double. - * @param z The z-coordinate as a double. - */ - constexpr Coordinate2D(double x, double z) - : x(static_cast(x)), z(static_cast(z)) {} - - /** - * @brief Constructs a Coordinate2D object from a Coordinate object. - * - * @param coord The Coordinate object. - */ - constexpr Coordinate2D(const Coordinate& coord) : x(coord.x), z(coord.z) {} - - /** - * @brief Constructs a Coordinate object from a Coordinate2D object and a - * y value. - * - * @param coord The Coordinate2D object. - * @param y The y value. - */ - Coordinate with_height(int y) const; - - /** - * @brief Adds two Coordinate2D objects. - * - * @param obj The Coordinate2D object to add. - * @return A new Coordinate2D object representing the sum of the two - * coordinates. - */ - Coordinate2D operator+(const Coordinate2D& obj) const; - - /** - * @brief Checks if two Coordinate2D objects are equal. - * - * @param obj The Coordinate2D object to compare with. - * @return True if the flat coordinates are equal, false otherwise. - */ - bool operator==(const Coordinate2D& obj) const; - - /** - * @brief Checks if two Coordinate2D objects are not equal. - * - * @param obj The Coordinate2D object to compare with. - * @return True if the flat coordinates are not equal, false otherwise. - */ - bool operator!=(const Coordinate2D& obj) const; - - /** - * @brief Subtracts one Coordinate2D object from another. - * - * @param obj The Coordinate2D object to subtract. - * @return A new Coordinate2D object representing the difference between - * the two coordinates. - */ - Coordinate2D operator-(const Coordinate2D& obj) const; - - /** - * @brief Outputs the Coordinate2D object to an ostream. - * - * @param out The output stream. - * @param coord The Coordinate2D object to output. - * @return The output stream with the Coordinate object's values. - */ - friend std::ostream& operator<<(std::ostream& out, - const Coordinate2D& coord); - - int x; - int z; -}; - -/** - * Stores a 3D cuboid of BlockTypes while preserving their relative location to - * the base point they were gathered at and each other. - */ -struct Chunk { - /** - * @brief An iterator for the Chunk's 3D block data. - * - * This iterator allows for range-based for loops and standard iterator - * operations over the 3D block data stored within a Chunk. It provides a - * linear interface to traverse the 3D grid of blocks, enabling sequential - * access to the elements stored in the chunk. - */ - struct Iterator { - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = BlockType; - using pointer = BlockType*; - using reference = BlockType&; - - /** - * @brief Constructs an iterator at the given pointer position. - * - * @param ptr Pointer to the position in the height array. - */ - Iterator(pointer ptr) : m_ptr(ptr) {} - - /** - * @brief Dereference the iterator to access the value at the current - * position. - * - * @return Reference to the current element. - */ - reference operator*() const { return *m_ptr; } - - /** - * @brief Access the pointer to the current element. - * - * @return Pointer to the current element. - */ - pointer operator->() { return m_ptr; } - - /** - * @brief Pre-increment operator. Advances the iterator to the next - * position. - * - * @return Reference to the updated iterator. - */ - Iterator& operator++() { - m_ptr++; - return *this; - } - - /** - * @brief Post-increment operator. Advances the iterator to the next - * position. - * - * @param int Unused dummy parameter to differentiate from prefix - * increment. - * @return Iterator to the original position before incrementing. - */ - Iterator operator++(int) { - Iterator tmp = *this; - ++(*this); - return tmp; - } - - /** - * @brief Equality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if both iterators point to the same position, false - * otherwise. - */ - friend bool operator==(const Iterator& a, const Iterator& b) { - return a.m_ptr == b.m_ptr; - }; - - /** - * @brief Inequality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if iterators point to different positions, false - * otherwise. - */ - friend bool operator!=(const Iterator& a, const Iterator& b) { - return a.m_ptr != b.m_ptr; - }; - - private: - pointer m_ptr; - }; - - /** - * @brief An iterator for the const Chunk's 3D block data. - * - * This iterator allows for range-based for loops and standard const - * iterator operations over the 3D block data stored within a Chunk. It - * provides a linear interface to traverse the 3D grid of blocks, enabling - * sequential immutable access to the elements stored in the chunk. - */ - struct ConstIterator { - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = BlockType; - using pointer = const BlockType*; - using reference = const BlockType&; - - /** - * @brief Constructs an iterator at the given pointer position. - * - * @param ptr Pointer to the position in the height array. - */ - ConstIterator(pointer ptr) : m_ptr(ptr) {} - - /** - * @brief Dereference the iterator to access the value at the current - * position. - * - * @return Reference to the current element. - */ - reference operator*() const { return *m_ptr; } - - /** - * @brief Access the pointer to the current element. - * - * @return Pointer to the current element. - */ - pointer operator->() { return m_ptr; } - - /** - * @brief Pre-increment operator. Advances the iterator to the next - * position. - * - * @return Reference to the updated iterator. - */ - ConstIterator& operator++() { - m_ptr++; - return *this; - } - - /** - * @brief Post-increment operator. Advances the iterator to the next - * position. - * - * @param int Unused dummy parameter to differentiate from prefix - * increment. - * @return Iterator to the original position before incrementing. - */ - ConstIterator operator++(int) { - ConstIterator tmp = *this; - ++(*this); - return tmp; - } - - /** - * @brief Equality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if both iterators point to the same position, false - * otherwise. - */ - friend bool operator==(const ConstIterator& a, const ConstIterator& b) { - return a.m_ptr == b.m_ptr; - }; - - /** - * @brief Inequality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if iterators point to different positions, false - * otherwise. - */ - friend bool operator!=(const ConstIterator& a, const ConstIterator& b) { - return a.m_ptr != b.m_ptr; - }; - - private: - pointer m_ptr; - }; - - Iterator begin() { return Iterator(&raw_data[0]); } - Iterator end() { return Iterator(&raw_data[_x_len * _y_len * _z_len]); } - ConstIterator begin() const { return ConstIterator(&raw_data[0]); } - ConstIterator end() const { - return ConstIterator(&raw_data[_x_len * _y_len * _z_len]); - } - - /** - * Initialized by copying from a flat vector of blocks - */ - Chunk(const Coordinate& loc1, const Coordinate& loc2, - const std::vector& block_list); - - ~Chunk(); - - Chunk& operator=(const Chunk& other) noexcept; - - /** - * Accesses the Minecraft block at absolute position pos and returns its - * BlockType if it is in the included area. - * @param pos: Abolute position in the Minecraft world to query BlockType - * for - * @return BlockType at specified location - */ - BlockType get_worldspace(const Coordinate& pos) const; - - /** - * Local equivalent of get_worldspace, equivalent to a 3D array access of - * the internal data. - * @param x: x element of array access - * @param y: y element of array access - * @param z: z element of array access - * @return BlockType at specified location - */ - BlockType get(int x, int y, int z) const; - - /** - * Gets the x length of the Chunk. - * @return x length of the Chunk - */ - int x_len() const; - - /** - * Gets the y length of the Chunk. - * @return y length of the Chunk - */ - int y_len() const; - - /** - * Gets the z length of the Chunk. - * @return z length of the Chunk - */ - int z_len() const; - - /** - * Gets the minimum coordinate in the Chunk. - * @return the minimum coordinate in the Chunk - */ - Coordinate base_pt() const; - - private: - Coordinate _base_pt; - int _y_len; - int _x_len; - int _z_len; - BlockType* raw_data; -}; - -/** - * Represents a 2D area of the world with the y coordinates of the highest - * non-air blocks at each (x,z) - */ -struct HeightMap { - /** - * @brief An iterator for the HeightMap structure. - * - * This iterator allows for range-based for loops and standard iterator - * operations over the height data stored within a HeightMap. - */ - struct Iterator { - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = int; - using pointer = int*; - using reference = int&; - - /** - * @brief Constructs an iterator at the given pointer position. - * - * @param ptr Pointer to the position in the height array. - */ - Iterator(pointer ptr) : m_ptr(ptr) {} - - /** - * @brief Dereference the iterator to access the value at the current - * position. - * - * @return Reference to the current element. - */ - reference operator*() const { return *m_ptr; } - - /** - * @brief Access the pointer to the current element. - * - * @return Pointer to the current element. - */ - pointer operator->() { return m_ptr; } - - /** - * @brief Pre-increment operator. Advances the iterator to the next - * position. - * - * @return Reference to the updated iterator. - */ - Iterator& operator++() { - m_ptr++; - return *this; - } - - /** - * @brief Post-increment operator. Advances the iterator to the next - * position. - * - * @param int Unused dummy parameter to differentiate from prefix - * increment. - * @return Iterator to the original position before incrementing. - */ - Iterator operator++(int) { - Iterator tmp = *this; - ++(*this); - return tmp; - } - - /** - * @brief Equality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if both iterators point to the same position, false - * otherwise. - */ - friend bool operator==(const Iterator& a, const Iterator& b) { - return a.m_ptr == b.m_ptr; - }; - - /** - * @brief Inequality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if iterators point to different positions, false - * otherwise. - */ - friend bool operator!=(const Iterator& a, const Iterator& b) { - return a.m_ptr != b.m_ptr; - }; - - private: - pointer m_ptr; - }; - - /** - * @brief An iterator for the const HeightMap structure. - * - * This iterator allows for range-based for loops and standard const - * iterator operations over the height data stored within a HeightMap. - */ - struct ConstIterator { - using iterator_category = std::forward_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = int; - using pointer = const int*; - using reference = const int&; - - /** - * @brief Constructs an iterator at the given pointer position. - * - * @param ptr Pointer to the position in the height array. - */ - ConstIterator(pointer ptr) : m_ptr(ptr) {} - - /** - * @brief Dereference the iterator to access the value at the current - * position. - * - * @return Reference to the current element. - */ - reference operator*() const { return *m_ptr; } - - /** - * @brief Access the pointer to the current element. - * - * @return Pointer to the current element. - */ - pointer operator->() { return m_ptr; } - - /** - * @brief Pre-increment operator. Advances the iterator to the next - * position. - * - * @return Reference to the updated iterator. - */ - ConstIterator& operator++() { - m_ptr++; - return *this; - } - - /** - * @brief Post-increment operator. Advances the iterator to the next - * position. - * - * @param int Unused dummy parameter to differentiate from prefix - * increment. - * @return Iterator to the original position before incrementing. - */ - ConstIterator operator++(int) { - ConstIterator tmp = *this; - ++(*this); - return tmp; - } - - /** - * @brief Equality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if both iterators point to the same position, false - * otherwise. - */ - friend bool operator==(const ConstIterator& a, const ConstIterator& b) { - return a.m_ptr == b.m_ptr; - }; - - /** - * @brief Inequality comparison operator. - * - * @param a First iterator to compare. - * @param b Second iterator to compare. - * @return true if iterators point to different positions, false - * otherwise. - */ - friend bool operator!=(const ConstIterator& a, const ConstIterator& b) { - return a.m_ptr != b.m_ptr; - }; - - private: - pointer m_ptr; - }; - - Iterator begin() { return Iterator(&raw_heights[0]); } - Iterator end() { return Iterator(&raw_heights[_x_len * _z_len]); } - ConstIterator begin() const { return ConstIterator(&raw_heights[0]); } - ConstIterator end() const { - return ConstIterator(&raw_heights[_x_len * _z_len]); - } - - HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, - const std::vector& heights); - - ~HeightMap(); - - HeightMap& operator=(const HeightMap& other) noexcept; - - /** - * Get the height using an offset from the origin/base point of the heights - * area - * @param x: x offset to access underlying array - * @param z: z offset to access underlying array - * @return: height at specified offset - */ - int get(int x, int z) const; - - /** - * Get the height at a Minecraft coordinate if saved inside the height map - * @param loc: 2D coordinate in Minecraft world to access in the map - * @return: height at specified coordinate - */ - int get_worldspace(const Coordinate2D& loc) const; - - /** - * Fill a coordinate inplace with the highest y coordinate at the `loc`'s x - * and z components. - * @param loc: Coordinate to fill y value for - */ - void fill_coord(Coordinate& out) const; - - /** - * Gets the x length of the HeightMap. - * @return x length of the HeightMap - */ - int x_len() const; - - /** - * Gets the z length of the HeightMap. - * @return z length of the HeightMap - */ - int z_len() const; - - /** - * Gets the minimum 2D coordinate in the HeightMap. - * @return the minimum 2D coordinate in the HeightMap. - */ - Coordinate2D base_pt() const; - - private: - Coordinate2D _base_pt; - int _x_len; - int _z_len; - int* raw_heights; -}; - -} // namespace mcpp diff --git a/src/coordinate.cpp b/src/coordinate.cpp index 37f6630..f5051d9 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -10,6 +10,14 @@ Coordinate Coordinate::operator+(const Coordinate& obj) const { return result; } +Coordinate Coordinate::operator+(const Coordinate2D& obj) const { + Coordinate result; + result.x = this->x + obj.x; + result.y = this->y; + result.z = this->z + obj.z; + return result; +} + bool Coordinate::operator==(const Coordinate& obj) const { return (this->x == obj.x) && (this->y == obj.y) && (this->z == obj.z); } @@ -44,4 +52,40 @@ std::ostream& operator<<(std::ostream& out, const Coordinate& coord) { out << to_string(coord); return out; } + +Coordinate Coordinate2D::with_height(int y) const { + return Coordinate(this->x, y, this->z); +} + +Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const { + Coordinate2D result; + result.x = this->x + obj.x; + result.z = this->z + obj.z; + return result; +} + +bool Coordinate2D::operator==(const Coordinate2D& obj) const { + return (this->x == obj.x) && (this->z == obj.z); +} + +bool Coordinate2D::operator!=(const Coordinate2D& obj) const { + return !(*this == obj); +} + +Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { + Coordinate2D result; + result.x = this->x - obj.x; + result.z = this->z - obj.z; + return result; +} + +std::string to_string(const Coordinate2D& coord) { + using std::to_string; + return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; +} + +std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord) { + out << to_string(coord); + return out; +} } // namespace mcpp diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 2c47e92..911b52d 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -2,7 +2,7 @@ #include namespace mcpp { -HeightMap::HeightMap(const Coordinate& loc1, const Coordinate& loc2, +HeightMap::HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, const std::vector& heights) { _base_pt = Coordinate{ std::min(loc1.x, loc2.x), @@ -47,5 +47,5 @@ uint16_t HeightMap::x_len() const { return _x_len; } uint16_t HeightMap::z_len() const { return _z_len; } -Coordinate HeightMap::base_pt() const { return _base_pt; } +Coordinate2D HeightMap::base_pt() const { return _base_pt; } } // namespace mcpp diff --git a/src/mcpp.cpp b/src/mcpp.cpp index abd808e..481b7df 100644 --- a/src/mcpp.cpp +++ b/src/mcpp.cpp @@ -122,7 +122,7 @@ HeightMap MinecraftConnection::getHeights(const Coordinate2D& loc1, std::vector parsed; split_response(response, parsed); - return {loc1, loc2, parsed}; + return HeightMap{loc1, loc2, parsed}; } } // namespace mcpp diff --git a/src/util.cpp b/src/util.cpp deleted file mode 100644 index 7f56ec0..0000000 --- a/src/util.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "../include/mcpp/util.h" -#include -#include -#include - -namespace mcpp { - -Coordinate Coordinate::operator+(const Coordinate& obj) const { - Coordinate result; - result.x = this->x + obj.x; - result.y = this->y + obj.y; - result.z = this->z + obj.z; - return result; -} - -Coordinate Coordinate::operator+(const Coordinate2D& obj) const { - Coordinate result; - result.x = this->x + obj.x; - result.y = this->y; - result.z = this->z + obj.z; - return result; -} - -bool Coordinate::operator==(const Coordinate& obj) const { - return (this->x == obj.x) && (this->y == obj.y) && (this->z == obj.z); -} - -bool Coordinate::operator!=(const Coordinate& obj) const { - return !(*this == obj); -} - -Coordinate Coordinate::operator-(const Coordinate& obj) const { - Coordinate result; - result.x = this->x - obj.x; - result.y = this->y - obj.y; - result.z = this->z - obj.z; - return result; -} - -Coordinate Coordinate::clone() const { - return Coordinate(this->x, this->y, this->z); -} - -std::string to_string(const Coordinate& coord) { - using std::to_string; - return "(" + to_string(coord.x) + "," + to_string(coord.y) + "," + - to_string(coord.z) + ")"; -} - -std::ostream& operator<<(std::ostream& out, const Coordinate& coord) { - out << to_string(coord); - return out; -} - -Coordinate Coordinate2D::with_height(int y) const { - return Coordinate(this->x, y, this->z); -} - -Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const { - Coordinate2D result; - result.x = this->x + obj.x; - result.z = this->z + obj.z; - return result; -} - -bool Coordinate2D::operator==(const Coordinate2D& obj) const { - return (this->x == obj.x) && (this->z == obj.z); -} - -bool Coordinate2D::operator!=(const Coordinate2D& obj) const { - return !(*this == obj); -} - -Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { - Coordinate2D result; - result.x = this->x - obj.x; - result.z = this->z - obj.z; - return result; -} - -std::string to_string(const Coordinate2D& coord) { - using std::to_string; - return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; -} - -std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord) { - out << to_string(coord); - return out; -} - -Chunk::Chunk(const Coordinate& loc1, const Coordinate& loc2, - const std::vector& block_list) { - Coordinate min{std::min(loc1.x, loc2.x), std::min(loc1.y, loc2.y), - std::min(loc1.z, loc2.z)}; - this->_base_pt = min.clone(); - - Coordinate dim = loc1 - loc2; - _x_len = std::abs(dim.x) + 1; - _y_len = std::abs(dim.y) + 1; - _z_len = std::abs(dim.z) + 1; - - this->raw_data = new BlockType[block_list.size()]; - std::copy(block_list.begin(), block_list.end(), raw_data); -} - -Chunk::~Chunk() { delete[] raw_data; } - -Chunk& Chunk::operator=(const Chunk& other) noexcept { - if (this != &other) { - // Clean up existing resource - delete[] raw_data; - - // Copy data from the other object - _base_pt = other._base_pt.clone(); - _x_len = other._x_len; - _y_len = other._y_len; - _z_len = other._z_len; - raw_data = new BlockType[_x_len * _y_len * _z_len]; - std::copy(other.raw_data, other.raw_data + _x_len * _y_len * _z_len, - raw_data); - } - return *this; -} - -BlockType Chunk::get(int x, int y, int z) const { - if ((x < 0 || y < 0 || z < 0) || - (x > _x_len - 1 || y > _y_len - 1 || z > _z_len - 1)) { - throw std::out_of_range("Out of bounds Chunk access at " + - to_string(Coordinate(x, y, z))); - } - return raw_data[y * _x_len * _z_len + x * _z_len + z]; -} - -BlockType Chunk::get_worldspace(const Coordinate& pos) const { - Coordinate array_pos = pos - _base_pt; - if ((array_pos.x < 0 || array_pos.y < 0 || array_pos.z < 0) || - (array_pos.x > _x_len - 1 || array_pos.y > _y_len - 1 || - array_pos.z > _z_len - 1)) { - throw std::out_of_range("Out of bounds Chunk access at " + - to_string(array_pos) + " (world coordinate " + - to_string(pos) + " )"); - } - return raw_data[array_pos.y * _x_len * _z_len + array_pos.x * _z_len + - array_pos.z]; -} - -int Chunk::x_len() const { return this->_x_len; } - -int Chunk::y_len() const { return this->_y_len; } - -int Chunk::z_len() const { return this->_z_len; } - -Coordinate Chunk::base_pt() const { return this->_base_pt.clone(); } - -HeightMap::HeightMap(const Coordinate2D& loc1, const Coordinate2D& loc2, - const std::vector& heights) { - _base_pt = Coordinate{ - std::min(loc1.x, loc2.x), - 0, - std::min(loc1.z, loc2.z), - }; - - _x_len = std::abs(loc1.x - loc2.x) + 1; - _z_len = std::abs(loc1.z - loc2.z) + 1; - - raw_heights = new int[heights.size()]; - std::copy(heights.begin(), heights.end(), raw_heights); -} - -HeightMap::~HeightMap() { delete[] raw_heights; } - -HeightMap& HeightMap::operator=(const HeightMap& other) noexcept { - if (this != &other) { - // Free the existing resource - delete[] raw_heights; - - // Copy data from the other object - _base_pt = other._base_pt; - _x_len = other._x_len; - _z_len = other._z_len; - - // Allocate memory and copy the heights - raw_heights = new int[_x_len * _z_len]; - std::copy(other.raw_heights, other.raw_heights + _x_len * _z_len, - raw_heights); - } - return *this; -} - -int HeightMap::get(int x, int z) const { - if ((x < 0 || x >= _x_len) || (z < 0 || z >= _z_len)) { - throw new std::out_of_range( - "Out of range access of heightmap at " + std::to_string(x) + "," + - std::to_string(z) + - " (worldspace x=" + std::to_string(_base_pt.x + x) + - ",z=" + std::to_string(_base_pt.z + z)); - } - // Get 2D from flat vector - return raw_heights[x * _z_len + z]; -} - -int HeightMap::get_worldspace(const Coordinate2D& loc) const { - return get(loc.x - _base_pt.x, loc.z - _base_pt.z); -} - -void HeightMap::fill_coord(Coordinate& out) const { - out.y = get_worldspace(out); -} - -int HeightMap::x_len() const { return this->_x_len; } - -int HeightMap::z_len() const { return this->_z_len; } - -Coordinate2D HeightMap::base_pt() const { return this->_base_pt; } - -} // namespace mcpp From 2c36c80109aa5470aa81e74fd2b8f3d05e1dd6f0 Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:37:50 +1000 Subject: [PATCH 15/19] fix: new tests with `Coordinate2D` --- test/minecraft_tests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/minecraft_tests.cpp b/test/minecraft_tests.cpp index 24df43a..177383c 100644 --- a/test/minecraft_tests.cpp +++ b/test/minecraft_tests.cpp @@ -384,14 +384,14 @@ TEST_CASE("HeightMap functionality") { // Copy assignment mc.setBlocks({10, 310, 10}, {20, 320, 20}, Blocks::AIR); mc.setBlocks({10, 310, 10}, {20, 310, 20}, Blocks::STONE); - auto map = mc.getHeights({10, 10, 10}, {20, 20, 20}); + auto map = mc.getHeights({10, 10}, {20, 20}); HeightMap map_copy = map; // Contains 310 CHECK_EQ(map.get(0, 0), map_copy.get(0, 0)); CHECK_EQ(map.get(0, 0), 310); // Reassignment mc.setBlock({10, 311, 10}, Blocks::STONE); - map = mc.getHeights({10, 10, 10}, {20, 20, 20}); // Now contains 311 + map = mc.getHeights({10, 10}, {20, 20}); // Now contains 311 CHECK_NE(map.get(0, 0), map_copy.get(0, 0)); CHECK_EQ(map.get(0, 0), 311); @@ -402,7 +402,7 @@ TEST_CASE("HeightMap functionality") { // Copy constructor auto map_copy2 = HeightMap(map); // Contains 310 mc.setBlock({10, 312, 10}, Blocks::STONE); - map = mc.getHeights({10, 10, 10}, {20, 20, 20}); // Now contains 312 + map = mc.getHeights({10, 10}, {20, 20}); // Now contains 312 CHECK_NE(map_copy2.get(0, 0), 312); CHECK_EQ(map.get(0, 0), 312); From f12d25438e04335bc6419dbf69783bd9a482dace Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:40:00 +1000 Subject: [PATCH 16/19] feat: make `mcpp::fillHeight` `const` --- include/mcpp/mcpp.h | 2 +- src/mcpp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mcpp/mcpp.h b/include/mcpp/mcpp.h index 7b57ecc..918c158 100644 --- a/include/mcpp/mcpp.h +++ b/include/mcpp/mcpp.h @@ -160,7 +160,7 @@ class MinecraftConnection { * @param loc 2D coordinate * @return Returns the coordinate with the filled-in height. */ - Coordinate fillHeight(Coordinate2D loc); + Coordinate fillHeight(Coordinate2D loc) const; /** * @brief Provides a scaled option of the getHeight call to allow for diff --git a/src/mcpp.cpp b/src/mcpp.cpp index 481b7df..dbec165 100644 --- a/src/mcpp.cpp +++ b/src/mcpp.cpp @@ -108,7 +108,7 @@ int MinecraftConnection::getHeight(Coordinate2D loc) const { return stoi(response); } -Coordinate MinecraftConnection::fillHeight(Coordinate2D loc) { +Coordinate MinecraftConnection::fillHeight(Coordinate2D loc) const { int y = this->getHeight(loc); return Coordinate(loc.x, y, loc.z); } From 0370a55b91bdaca82e32f8ce099bf3a644064be5 Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:42:39 +1000 Subject: [PATCH 17/19] feat: hash `Coordinate2D` --- include/mcpp/coordinate.h | 9 +++++++++ src/coordinate.cpp | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/mcpp/coordinate.h b/include/mcpp/coordinate.h index 5711524..3ab1186 100644 --- a/include/mcpp/coordinate.h +++ b/include/mcpp/coordinate.h @@ -176,6 +176,15 @@ struct Coordinate2D { */ Coordinate2D operator-(const Coordinate2D& obj) const; + /** + * @brief Implements hash algorithm for Coordinate2D object using non-negative + * mapping and weighted coordinate values. + * + * @param obj The Coordinate2D object to hash. + * @return Hash of Coordinate2D object. + */ + std::size_t operator()(const Coordinate2D& obj) const; + /** * @brief Outputs the Coordinate2D object to an ostream. * diff --git a/src/coordinate.cpp b/src/coordinate.cpp index f5051d9..817e834 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -79,6 +79,16 @@ Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { return result; } +std::size_t Coordinate2D::operator()(const mcpp::Coordinate2D& obj) const { + int lower = -3e7, upper = 3e7; + size_t base = upper - lower + 1; + + size_t nx = obj.x - lower; + size_t nz = obj.z - lower; + + return nx * base + nz; +} + std::string to_string(const Coordinate2D& coord) { using std::to_string; return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; From add867c22076185d080fa00bfce9ff25b874e459 Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:44:15 +1000 Subject: [PATCH 18/19] chore: format --- src/coordinate.cpp | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/coordinate.cpp b/src/coordinate.cpp index 817e834..74a10f3 100644 --- a/src/coordinate.cpp +++ b/src/coordinate.cpp @@ -11,11 +11,11 @@ Coordinate Coordinate::operator+(const Coordinate& obj) const { } Coordinate Coordinate::operator+(const Coordinate2D& obj) const { - Coordinate result; - result.x = this->x + obj.x; - result.y = this->y; - result.z = this->z + obj.z; - return result; + Coordinate result; + result.x = this->x + obj.x; + result.y = this->y; + result.z = this->z + obj.z; + return result; } bool Coordinate::operator==(const Coordinate& obj) const { @@ -53,30 +53,26 @@ std::ostream& operator<<(std::ostream& out, const Coordinate& coord) { return out; } -Coordinate Coordinate2D::with_height(int y) const { - return Coordinate(this->x, y, this->z); -} +Coordinate Coordinate2D::with_height(int y) const { return Coordinate(this->x, y, this->z); } Coordinate2D Coordinate2D::operator+(const Coordinate2D& obj) const { - Coordinate2D result; - result.x = this->x + obj.x; - result.z = this->z + obj.z; - return result; + Coordinate2D result; + result.x = this->x + obj.x; + result.z = this->z + obj.z; + return result; } bool Coordinate2D::operator==(const Coordinate2D& obj) const { - return (this->x == obj.x) && (this->z == obj.z); + return (this->x == obj.x) && (this->z == obj.z); } -bool Coordinate2D::operator!=(const Coordinate2D& obj) const { - return !(*this == obj); -} +bool Coordinate2D::operator!=(const Coordinate2D& obj) const { return !(*this == obj); } Coordinate2D Coordinate2D::operator-(const Coordinate2D& obj) const { - Coordinate2D result; - result.x = this->x - obj.x; - result.z = this->z - obj.z; - return result; + Coordinate2D result; + result.x = this->x - obj.x; + result.z = this->z - obj.z; + return result; } std::size_t Coordinate2D::operator()(const mcpp::Coordinate2D& obj) const { @@ -90,12 +86,12 @@ std::size_t Coordinate2D::operator()(const mcpp::Coordinate2D& obj) const { } std::string to_string(const Coordinate2D& coord) { - using std::to_string; - return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; + using std::to_string; + return "(" + to_string(coord.x) + "," + to_string(coord.z) + ")"; } std::ostream& operator<<(std::ostream& out, const Coordinate2D& coord) { - out << to_string(coord); - return out; + out << to_string(coord); + return out; } } // namespace mcpp From 3356186324840b3395eef1a33a74e3e9059fd593 Mon Sep 17 00:00:00 2001 From: darcy Date: Sat, 21 Jun 2025 13:52:28 +1000 Subject: [PATCH 19/19] fix: `HeightMap::get_worldspace` takes `Coordinate2D` --- include/mcpp/heightmap.h | 4 ++-- src/heightmap.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mcpp/heightmap.h b/include/mcpp/heightmap.h index a71d0ad..54b864a 100644 --- a/include/mcpp/heightmap.h +++ b/include/mcpp/heightmap.h @@ -46,10 +46,10 @@ struct HeightMap { /** * Get the height at a Minecraft coordinate if saved inside the height map - * @param loc: Coordinate in Minecraft world to access in the map + * @param loc: Coordinate2D in Minecraft world to access in the map * @return: height at specified coordinate */ - int16_t get_worldspace(const Coordinate& loc) const; + int16_t get_worldspace(const Coordinate2D& loc) const; /** * Fill a coordinate inplace with the highest y coordinate at the `loc`'s x diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 911b52d..d043b04 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -37,7 +37,7 @@ int16_t HeightMap::get(int x, int z) const { return _raw_heights[(x * _z_len) + z]; } -int16_t HeightMap::get_worldspace(const Coordinate& loc) const { +int16_t HeightMap::get_worldspace(const Coordinate2D& loc) const { return get(loc.x - _base_pt.x, loc.z - _base_pt.z); }