| 252 | } |
| 253 | |
| 254 | static bool plant_in_cuboid(const df::plant *plant, const cuboid &bounds) |
| 255 | { // Will detect tree tiles |
| 256 | if (bounds.containsPos(plant->pos)) |
| 257 | return true; |
| 258 | else if (!plant->tree_info) |
| 259 | return false; |
| 260 | |
| 261 | auto &pos = plant->pos; |
| 262 | auto &t = *(plant->tree_info); |
| 263 | |
| 264 | // Northwest x/y pos of tree bounds |
| 265 | int x_NW = pos.x - (t.dim_x >> 1); |
| 266 | int y_NW = pos.y - (t.dim_y >> 1); |
| 267 | |
| 268 | if (!cuboid(std::max(0, x_NW), std::max(0, y_NW), std::max(0, pos.z - t.roots_depth), |
| 269 | x_NW + t.dim_x, y_NW + t.dim_y, pos.z + t.body_height - 1).clamp(bounds).isValid()) |
| 270 | { // No intersection of tree bounds with cuboid |
| 271 | return false; |
| 272 | } |
| 273 | |
| 274 | int xy_size = t.dim_x * t.dim_y; |
| 275 | // Iterate tree body |
| 276 | for (int z_idx = 0; z_idx < t.body_height; z_idx++) |
| 277 | for (int xy_idx = 0; xy_idx < xy_size; xy_idx++) |
| 278 | if ((t.body[z_idx][xy_idx].whole & 0x7F) != 0 && // Any non-blocked |
| 279 | bounds.containsPos(x_NW + xy_idx % t.dim_x, y_NW + xy_idx / t.dim_x, pos.z + z_idx)) |
| 280 | { |
| 281 | return true; |
| 282 | } |
| 283 | |
| 284 | // Iterate tree roots |
| 285 | for (int z_idx = 0; z_idx < t.roots_depth; z_idx++) |
| 286 | for (int xy_idx = 0; xy_idx < xy_size; xy_idx++) |
| 287 | if ((t.roots[z_idx][xy_idx].whole & 0x7F) != 0 && // Any non-blocked |
| 288 | bounds.containsPos(x_NW + xy_idx % t.dim_x, y_NW + xy_idx / t.dim_x, pos.z - z_idx - 1)) |
| 289 | { |
| 290 | return true; |
| 291 | } |
| 292 | |
| 293 | return false; |
| 294 | } |
| 295 | |
| 296 | command_result df_grow(color_ostream &out, const cuboid &bounds, const plant_options &options, vector<int32_t> *filter = nullptr) |
| 297 | { |
no test coverage detected