| 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. |
| 222 | if (!valid_tile(out, options, block, tx, ty)) { |
| 223 | DEBUG(log, out).print("Skipping invalid tile.\n"); |
| 224 | return false; |
| 225 | } |
| 226 | // Gather grass events for consideration. |
| 227 | vector<df::block_square_event_grassst *> consider_grev; |
| 228 | for (auto blev : block->block_events) |
| 229 | if (auto gr_ev = virtual_cast<df::block_square_event_grassst>(blev)) |
| 230 | consider_grev.push_back(gr_ev); |
| 231 | |
| 232 | df::block_square_event_grassst *forced_grev = NULL; |
| 233 | bool success = false; // Determine if max regrass worked. |
| 234 | |
| 235 | for (auto gr_ev : consider_grev) |
| 236 | { // Try to refill existing events. |
| 237 | if (options.max_grass) |
| 238 | { // Refill all. |
| 239 | gr_ev->amount[tx][ty] = 100; |
| 240 | success = true; |
| 241 | } |
| 242 | else if (gr_ev->amount[tx][ty] > 0) |
| 243 | { // Refill first non-zero grass. |
| 244 | DEBUG(log, out).print("Refilling existing grass (ID {}).\n", gr_ev->plant_index); |
| 245 | gr_ev->amount[tx][ty] = 100; |
| 246 | return true; |
| 247 | } |
| 248 | |
| 249 | if (options.force && gr_ev->plant_index == options.forced_plant) |
| 250 | forced_grev = gr_ev; // Avoid allocating a new event. |
| 251 | } |
| 252 | if (options.force) |
| 253 | block->occupancy[tx][ty].bits.no_grow = false; |
| 254 | |
| 255 | vector<int32_t> valid_grasses; |
| 256 | if (options.new_grass || !options.max_grass) // Find out what belongs. |
| 257 | grasses_for_tile(out, valid_grasses, block, tx, ty); |
| 258 | |
| 259 | if (options.new_grass && !valid_grasses.empty()) { |
| 260 | TRACE(log, out).print("Handling new grasses...\n"); |
| 261 | auto new_grasses(valid_grasses); // Copy vector. |
| 262 | |
| 263 | for (auto gr_ev : consider_grev) |
| 264 | { // These grass events are already present. |
| 265 | if (erase_from_vector(new_grasses, gr_ev->plant_index)) { |
| 266 | TRACE(log, out).print("Grass (ID {}) already present.\n", gr_ev->plant_index); |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | for (auto id : new_grasses) { |
| 271 | DEBUG(log, out).print("Allocating new grass event (ID {}).\n", id); |
| 272 | auto gr_ev = df::allocate<df::block_square_event_grassst>(); |
| 273 | if (!gr_ev) { |
| 274 | out.printerr("Failed to allocate new grass event! Aborting loop.\n"); |
| 275 | break; |
| 276 | } |
| 277 | gr_ev->plant_index = id; |
no test coverage detected