dfhack
dfhack copied to clipboard
Cuboid struct/class for df::coord bounds
Testing if a df::coord is inside a given box is an issue that comes up when dealing with map positions. There doesn't seem to be anything handy in the DFHack library, so every tool has to implement its own logic.
Not sure where the struct should be defined. MiscUtils?
I created an example while working on an improved plugins/plants.cpp:
struct cuboid
{
int16_t x_min = -1;
int16_t x_max = -1;
int16_t y_min = -1;
int16_t y_max = -1;
int16_t z_min = -1;
int16_t z_max = -1;
bool isValid() const
{ // False if any bound is < 0
return x_min >= 0 && x_max >= 0 &&
y_min >= 0 && y_max >= 0 &&
z_min >= 0 && z_max >= 0;
}
bool addPos(int16_t x, int16_t y, int16_t z)
{ // Expand cuboid to include point. Return true if bounds changed
if (x < 0 || y < 0 || z < 0 || (isValid() && testPos(x, y, z)))
return false;
x_min = (x_min < 0 || x < x_min) ? x : x_min;
x_max = (x_max < 0 || x > x_max) ? x : x_max;
y_min = (y_min < 0 || y < y_min) ? y : y_min;
y_max = (y_max < 0 || y > y_max) ? y : y_max;
z_min = (z_min < 0 || z < z_min) ? z : z_min;
z_max = (z_max < 0 || z > z_max) ? z : z_max;
return true;
}
inline bool addPos(df::coord pos) { return addPos(pos.x, pos.y, pos.z); }
bool testPos(int16_t x, int16_t y, int16_t z) const
{ // Return true if point inside cuboid. Make sure cuboid is valid first!
return x >= x_min && x <= x_max &&
y >= y_min && y <= y_max &&
z >= z_min && z <= z_max;
}
inline bool testPos(df::coord pos) const { return testPos(pos.x, pos.y, pos.z); }
};
This could probably be refined. (I don't know if there's a use-case for supporting negative values, but this implementation doesn't.)
Some existing plugins that could make use of this include plugins/blueprint.cpp and plugins/regrass.cpp. gui/teleport.lua could probably make use of this if Lua doesn't make that a pain.