| 848 | } |
| 849 | |
| 850 | static void create_boulders(color_ostream &out, |
| 851 | const item_coords_t &item_coords, |
| 852 | const dig_now_options &options, |
| 853 | df::unit * creator) { |
| 854 | df::historical_entity *civ = df::historical_entity::find(creator->civ_id); |
| 855 | df::world_site *site = World::isFortressMode() ? |
| 856 | df::world_site::find(plotinfo->site_id) : NULL; |
| 857 | |
| 858 | std::vector<df::reaction_reagent *> in_reag; |
| 859 | std::vector<df::item *> in_items; |
| 860 | |
| 861 | DFCoord dump_pos; |
| 862 | if (Maps::isValidTilePos(options.dump_pos)) { |
| 863 | dump_pos = simulate_fall(options.dump_pos); |
| 864 | if (!Maps::ensureTileBlock(dump_pos)) |
| 865 | out.printerr("Invalid dump tile coordinates! Ensure the --dump" |
| 866 | " option specifies an open, non-wall tile."); |
| 867 | } |
| 868 | |
| 869 | for (auto entry : item_coords) { |
| 870 | df::reaction_product_itemst *prod = |
| 871 | df::allocate<df::reaction_product_itemst>(); |
| 872 | const std::vector<DFCoord> &coords = entry.second; |
| 873 | |
| 874 | prod->item_type = entry.first.first; |
| 875 | prod->item_subtype = -1; |
| 876 | prod->mat_type = entry.first.second.mat_type; |
| 877 | prod->mat_index = entry.first.second.mat_index; |
| 878 | prod->probability = 100; |
| 879 | prod->product_dimension = 1; |
| 880 | |
| 881 | std::vector<df::reaction_product*> out_products; |
| 882 | std::vector<df::item *> out_items; |
| 883 | |
| 884 | size_t remaining_items = coords.size(); |
| 885 | while (remaining_items > 0) { |
| 886 | int16_t batch_size = std::min(remaining_items, |
| 887 | static_cast<size_t>(INT16_MAX)); |
| 888 | prod->count = batch_size; |
| 889 | remaining_items -= batch_size; |
| 890 | prod->produce(creator, &out_products, &out_items, &in_reag, &in_items, |
| 891 | 1, job_skill::NONE, 0, civ, site, NULL); |
| 892 | } |
| 893 | |
| 894 | size_t num_items = out_items.size(); |
| 895 | if (num_items != coords.size()) { |
| 896 | MaterialInfo material; |
| 897 | material.decode(prod->mat_type, prod->mat_index); |
| 898 | out.printerr("unexpected number of {} {} produced: expected {}, got {}.\n", |
| 899 | material.toString(), ENUM_KEY_STR(item_type, prod->item_type), |
| 900 | coords.size(), num_items); |
| 901 | num_items = std::min(num_items, entry.second.size()); |
| 902 | } |
| 903 | |
| 904 | for (size_t i = 0; i < num_items; ++i) { |
| 905 | DFCoord pos = Maps::isValidTilePos(dump_pos) ? |
| 906 | dump_pos : simulate_fall(coords[i]); |
| 907 | if (!Maps::ensureTileBlock(pos)) { |
no test coverage detected