| 292 | } |
| 293 | |
| 294 | static void fix_map(color_ostream &out, bool dry_run) { |
| 295 | static const uint32_t occ_mask = df::tile_occupancy::mask_building | df::tile_occupancy::mask_unit | |
| 296 | df::tile_occupancy::mask_unit_grounded | df::tile_occupancy::mask_item; |
| 297 | |
| 298 | Expected expected; |
| 299 | |
| 300 | // set expected building occupancy |
| 301 | for (auto bld : world->buildings.all) |
| 302 | scan_building(out, bld, expected); |
| 303 | |
| 304 | // set expected unit occupancy |
| 305 | for (auto unit : world->units.active) |
| 306 | scan_unit(unit, expected); |
| 307 | |
| 308 | // set expected item occupancy |
| 309 | for (auto item : world->items.other.IN_PLAY) |
| 310 | scan_item(item, expected); |
| 311 | |
| 312 | // check against expected values and fix |
| 313 | for (auto block : world->map.map_blocks) { |
| 314 | // check/fix order of map block item vector |
| 315 | normalize_item_vector(out, block, dry_run); |
| 316 | reconcile_block_items(out, expected.block_items(block), block, dry_run); |
| 317 | |
| 318 | // reconcile occupancy of each tile against expected values |
| 319 | int z = block->map_pos.z; |
| 320 | for (int yoff = 0; yoff < 16; ++yoff) { |
| 321 | int y = block->map_pos.y + yoff; |
| 322 | for (int xoff = 0; xoff < 16; ++xoff) { |
| 323 | int x = block->map_pos.x + xoff; |
| 324 | auto expected_occ = expected.occ(x, y, z); |
| 325 | auto expected_bld = expected.bld(x, y, z); |
| 326 | if (!expected_occ || !expected_bld) { |
| 327 | TRACE(log,out).print("pos out of bounds ({}, {}, {})\n", x, y, z); |
| 328 | continue; |
| 329 | } |
| 330 | df::tile_occupancy &block_occ = block->occupancy[xoff][yoff]; |
| 331 | if (*expected_bld || (expected_occ->whole & occ_mask) != (block_occ.whole & occ_mask)) { |
| 332 | DEBUG(log,out).print("reconciling occupancy at ({}, {}, {}) (bld={}, 0x{:x} ?= 0x{:x})\n", |
| 333 | x, y, z, static_cast<void*>(*expected_bld), expected_occ->whole & occ_mask, block_occ.whole & occ_mask); |
| 334 | reconcile_map_tile(out, *expected_bld, *expected_occ, block_occ, dry_run, x, y, z); |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | } |
| 339 | |
| 340 | INFO(log,out).print("verified {} buildings, {} units, {} items, {} map blocks, and {} map tiles\n", |
| 341 | world->buildings.all.size(), world->units.active.size(), world->items.other.IN_PLAY.size(), |
| 342 | world->map.map_blocks.size(), expected.get_size()); |
| 343 | } |
| 344 | |
| 345 | DFHACK_PLUGIN_LUA_FUNCTIONS{ |
| 346 | DFHACK_LUA_FUNCTION(fix_tile), |
nothing calls this directly
no test coverage detected