| 168 | } |
| 169 | |
| 170 | static void grasses_for_tile(color_ostream &out, vector<int32_t> &vec, df::map_block *block, int tx, int ty) |
| 171 | { // Fill vector with sorted valid grass IDs. |
| 172 | vec.clear(); |
| 173 | if (block->occupancy[tx][ty].bits.no_grow) { |
| 174 | TRACE(log, out).print("Skipping grass collection: no_grow\n"); |
| 175 | return; |
| 176 | } |
| 177 | // TODO: Use world.area_grasses.layer_grasses[] if not options.new_grass? |
| 178 | TRACE(log, out).print("Collecting grasses...\n"); |
| 179 | if (block->designation[tx][ty].bits.subterranean) { |
| 180 | for (auto p_raw : world->raws.plants.grasses) |
| 181 | { // Sorted by df::plant_raw::index |
| 182 | if (p_raw->flags.is_set(plant_raw_flags::BIOME_SUBTERRANEAN_WATER)) { |
| 183 | TRACE(log, out).print("Cave grass: {}\n", p_raw->id); |
| 184 | vec.push_back(p_raw->index); |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | else |
| 189 | { // Surface |
| 190 | auto rgn_pos = Maps::getBlockTileBiomeRgn(block, df::coord2d(tx, ty)); |
| 191 | if (!rgn_pos.isValid()) |
| 192 | { // No biome (happens in sky). |
| 193 | TRACE(log, out).print("No grass: No biome region!\n"); |
| 194 | return; |
| 195 | } |
| 196 | |
| 197 | auto &biome_info = *Maps::getRegionBiome(rgn_pos); // TODO: Cache grasses based on region? |
| 198 | auto plant_biome_flag = ENUM_ATTR(biome_type, plant_raw_flag, Maps::getBiomeType(rgn_pos.x, rgn_pos.y)); |
| 199 | |
| 200 | bool good = (biome_info.evilness < 33); |
| 201 | bool evil = (biome_info.evilness > 65); |
| 202 | bool savage = (biome_info.savagery > 65); |
| 203 | |
| 204 | for (auto p_raw : world->raws.plants.grasses) |
| 205 | { // Sorted by df::plant_raw::index |
| 206 | auto &flags = p_raw->flags; |
| 207 | if (flags.is_set(plant_biome_flag) && |
| 208 | (good || !flags.is_set(plant_raw_flags::GOOD)) && |
| 209 | (evil || !flags.is_set(plant_raw_flags::EVIL)) && |
| 210 | (savage || !flags.is_set(plant_raw_flags::SAVAGE))) |
| 211 | { |
| 212 | TRACE(log, out).print("Surface grass: {}\n", p_raw->id); |
| 213 | vec.push_back(p_raw->index); |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | TRACE(log, out).print("Done collecting grasses.\n"); |
| 218 | } |
| 219 | |
| 220 | static bool regrass_events(color_ostream &out, const regrass_options &options, df::map_block *block, int tx, int ty) |
| 221 | { // Utility fn to modify grass block events. |
no test coverage detected