Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions example/pyramid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Comment thread
dxrcy marked this conversation as resolved.
Outdated
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));
Expand Down
16 changes: 8 additions & 8 deletions include/mcpp/mcpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,30 +125,30 @@ 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
* considerable performance gains.
*
* \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
122 changes: 115 additions & 7 deletions include/mcpp/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*
Expand Down Expand Up @@ -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<int>(x)), z(static_cast<int>(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;
Comment thread
dxrcy marked this conversation as resolved.
Outdated

/**
* @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.
Expand Down Expand Up @@ -343,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<int>& heights);

~HeightMap();
Expand All @@ -361,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
Expand All @@ -386,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;
Expand Down
9 changes: 5 additions & 4 deletions src/mcpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
42 changes: 39 additions & 3 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Comment thread
dxrcy marked this conversation as resolved.
Outdated

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<BlockType>& block_list) {
Coordinate min{std::min(loc1.x, loc2.x), std::min(loc1.y, loc2.y),
Expand Down Expand Up @@ -120,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<int>& heights) {
_base_pt = Coordinate{
std::min(loc1.x, loc2.x),
Expand Down Expand Up @@ -167,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);
}

Expand All @@ -179,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
2 changes: 1 addition & 1 deletion test/minecraft_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down