| 294 | } |
| 295 | |
| 296 | command_result df_grow(color_ostream &out, const cuboid &bounds, const plant_options &options, vector<int32_t> *filter = nullptr) |
| 297 | { |
| 298 | if (!bounds.isValid()) |
| 299 | { |
| 300 | out.printerr("Invalid cuboid! ({}:{}, {}:{}, {}:{})\n", |
| 301 | bounds.x_min, bounds.x_max, bounds.y_min, bounds.y_max, bounds.z_min, bounds.z_max); |
| 302 | return CR_FAILURE; |
| 303 | } |
| 304 | |
| 305 | bool do_filter = filter && !filter->empty(); |
| 306 | if (do_filter) // Sort filter vector |
| 307 | std::sort(filter->begin(), filter->end()); |
| 308 | |
| 309 | int32_t age = options.age < 0 ? sapling_to_tree_threshold : options.age; // Enforce default |
| 310 | bool do_trees = age > sapling_to_tree_threshold; |
| 311 | |
| 312 | int grown = 0, grown_trees = 0; |
| 313 | for (auto plant : world->plants.all) |
| 314 | { |
| 315 | if (ENUM_ATTR(plant_type, is_shrub, plant->type)) |
| 316 | continue; // Shrub |
| 317 | else if (!plant_in_cuboid(plant, bounds)) |
| 318 | continue; // Outside cuboid |
| 319 | else if (do_filter && (vector_contains(*filter, (int32_t)plant->material) == options.filter_ex)) |
| 320 | continue; // Filtered out |
| 321 | else if (plant->tree_info) |
| 322 | { // Tree |
| 323 | if (do_trees && !plant->damage_flags.bits.dead && plant->grow_counter < age) |
| 324 | { |
| 325 | if (!options.dry_run) |
| 326 | plant->grow_counter = age; |
| 327 | grown_trees++; |
| 328 | } |
| 329 | continue; // Next plant |
| 330 | } |
| 331 | |
| 332 | auto tt = Maps::getTileType(plant->pos); |
| 333 | if (!tt || tileShape(*tt) != tiletype_shape::SAPLING) |
| 334 | { |
| 335 | out.printerr("Invalid sapling tiletype at ({}, {}, {}): {}\n", |
| 336 | plant->pos.x, plant->pos.y, plant->pos.z, |
| 337 | tt ? ENUM_KEY_STR(tiletype, *tt) : "No map block!"); |
| 338 | continue; // Bad tiletype |
| 339 | } |
| 340 | else if (*tt == tiletype::SaplingDead) |
| 341 | *tt = tiletype::Sapling; // Revive sapling |
| 342 | |
| 343 | if (!options.dry_run) |
| 344 | { |
| 345 | plant->damage_flags.bits.dead = false; |
| 346 | plant->grow_counter = age; |
| 347 | } |
| 348 | grown++; |
| 349 | } |
| 350 | |
| 351 | if (do_trees) |
| 352 | out.print("{} saplings and {} trees{} set to grow.\n", grown, grown_trees, options.dry_run ? " would be" : ""); |
| 353 | else |
no test coverage detected