| 66 | command_result df_regrass(color_ostream &out, vector<string> ¶meters); |
| 67 | |
| 68 | static bool valid_tile(color_ostream &out, regrass_options options, df::map_block *block, int tx, int ty) |
| 69 | { // Is valid tile for regrass. |
| 70 | auto des = block->designation[tx][ty]; |
| 71 | auto tt = block->tiletype[tx][ty]; |
| 72 | auto shape = tileShape(tt); |
| 73 | auto mat = tileMaterial(tt); |
| 74 | auto spec = tileSpecial(tt); |
| 75 | |
| 76 | if (mat == tiletype_material::GRASS_LIGHT || |
| 77 | mat == tiletype_material::GRASS_DARK || |
| 78 | mat == tiletype_material::PLANT) // Shrubs and saplings can have grass underneath. |
| 79 | { // Refill existing grass. |
| 80 | TRACE(log, out).print("Valid tile: Grass/Shrub/Sapling\n"); |
| 81 | return true; |
| 82 | } |
| 83 | else if (tt == tiletype::TreeTrunkPillar || tt == tiletype::TreeTrunkInterior || |
| 84 | (tt >= tiletype::TreeTrunkThickN && tt <= tiletype::TreeTrunkThickSE)) |
| 85 | { // Trees can have grass for ground level tiles. |
| 86 | auto p = df::coord(block->map_pos.x + tx, block->map_pos.y + ty, block->map_pos.z); |
| 87 | auto plant = Maps::getPlantAtTile(p); |
| 88 | if (plant && plant->pos.z == p.z) |
| 89 | { |
| 90 | TRACE(log, out).print("Valid tile: Tree\n"); |
| 91 | return true; // Ground tile. |
| 92 | } |
| 93 | |
| 94 | TRACE(log, out).print("Invalid tile: Tree\n"); |
| 95 | return false; // Not ground tile. |
| 96 | } |
| 97 | else if (des.bits.flow_size > (des.bits.liquid_type == tile_liquid::Magma ? 0U : 3U)) |
| 98 | { // Under water/magma (df::plant_raw::shrub_drown_level is usually 4). |
| 99 | TRACE(log, out).print("Invalid tile: Liquid\n"); |
| 100 | return false; |
| 101 | } |
| 102 | else if (shape != tiletype_shape::FLOOR && |
| 103 | shape != tiletype_shape::RAMP && |
| 104 | shape != tiletype_shape::STAIR_UP && |
| 105 | shape != tiletype_shape::STAIR_DOWN && |
| 106 | shape != tiletype_shape::STAIR_UPDOWN) |
| 107 | { |
| 108 | TRACE(log, out).print("Invalid tile: Shape\n"); |
| 109 | return false; |
| 110 | } |
| 111 | else if (block->occupancy[tx][ty].bits.building > |
| 112 | (options.buildings ? tile_building_occ::Passable : tile_building_occ::None)) |
| 113 | { // Avoid stockpiles and planned/passable buildings unless enabled. |
| 114 | TRACE(log, out).print("Invalid tile: Building ({})\n", |
| 115 | ENUM_KEY_STR(tile_building_occ, block->occupancy[tx][ty].bits.building).c_str()); |
| 116 | return false; |
| 117 | } |
| 118 | else if (!options.force && block->occupancy[tx][ty].bits.no_grow) { |
| 119 | TRACE(log, out).print("Invalid tile: no_grow\n"); |
| 120 | return false; |
| 121 | } |
| 122 | else if (mat == tiletype_material::SOIL) { |
| 123 | if (spec == tiletype_special::FURROWED || spec == tiletype_special::WET) |
| 124 | { // Dirt road or beach. |
| 125 | TRACE(log, out).print("Invalid tile: Furrowed/Wet\n"); |
no test coverage detected