| 259 | } |
| 260 | |
| 261 | void process(color_ostream& out) |
| 262 | { |
| 263 | // mark that we have recently run |
| 264 | cycle_timestamp = world->frame_counter; |
| 265 | |
| 266 | find_plantable_plants(); |
| 267 | |
| 268 | lastCounts.clear(); |
| 269 | |
| 270 | const uint32_t bad_flags{ |
| 271 | #define F(x) (df::item_flags::Mask::mask_##x) |
| 272 | F(dump) | F(forbid) | F(garbage_collect) | |
| 273 | F(hostile) | F(on_fire) | F(rotten) | F(trader) | |
| 274 | F(in_building) | F(construction) | F(artifact) |
| 275 | #undef F |
| 276 | }; |
| 277 | |
| 278 | // have to scan both items[PLANT] and items[PLANT_GROWTH] because agricultural products can be either |
| 279 | |
| 280 | auto count = [&, this](df::item* i) { |
| 281 | auto mat = i->getMaterialIndex(); |
| 282 | if ((i->flags.whole & bad_flags) == 0 && |
| 283 | plantable_plants.count(mat) > 0) |
| 284 | { |
| 285 | lastCounts[mat] += i->getStackSize(); |
| 286 | } |
| 287 | }; |
| 288 | |
| 289 | for (auto i : world->items.other[df::items_other_id::PLANT]) |
| 290 | count(i); |
| 291 | for (auto i : world->items.other[df::items_other_id::PLANT_GROWTH]) |
| 292 | count(i); |
| 293 | |
| 294 | std::map<df::biome_type, std::set<int>> plants; |
| 295 | |
| 296 | for (auto& plantable : plantable_plants) |
| 297 | { |
| 298 | df::plant_raw* plant = world->raws.plants.all[plantable.first]; |
| 299 | if (lastCounts[plant->index] < getThreshold(plant->index)) |
| 300 | for (auto biome : plantable.second) |
| 301 | { |
| 302 | plants[biome].insert(plant->index); |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | std::map<df::biome_type, std::vector<df::building_farmplotst*>> farms; |
| 307 | |
| 308 | for (auto& bb : world->buildings.other[df::buildings_other_id::FARM_PLOT]) |
| 309 | { |
| 310 | auto farm = virtual_cast<df::building_farmplotst>(bb); |
| 311 | if (farm->flags.bits.exists) |
| 312 | { |
| 313 | df::biome_type biome; |
| 314 | if (Maps::getTileDesignation(bb->centerx, bb->centery, bb->z)->bits.subterranean) |
| 315 | biome = biome_type::SUBTERRANEAN_WATER; |
| 316 | else { |
| 317 | df::coord2d region(Maps::getTileBiomeRgn(df::coord(bb->centerx, bb->centery, bb->z))); |
| 318 | biome = Maps::getBiomeType(region.x, region.y); |
no test coverage detected