Skip to content

Commit 6687d3a

Browse files
committed
get expected values
1 parent 2e1eb21 commit 6687d3a

2 files changed

Lines changed: 74 additions & 57 deletions

File tree

plugins/fix-occupancy.cpp

Lines changed: 72 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "modules/Maps.h"
77
#include "modules/Units.h"
88

9+
#include "df/building.h"
910
#include "df/item.h"
1011
#include "df/map_block.h"
1112
#include "df/tile_occupancy.h"
@@ -43,7 +44,7 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginComman
4344
DEBUG(log, out).print("initializing %s\n", plugin_name);
4445

4546
commands.push_back(PluginCommand(
46-
plugin_name,
47+
"fix/occupancy",
4748
"Fix phantom occupancy issues.",
4849
do_command));
4950

@@ -142,8 +143,8 @@ static void fix_tile(color_ostream &out, df::coord pos, bool dry_run) {
142143
}
143144
}
144145

146+
/*
145147
static void fix_map_items(color_ostream &out, bool dry_run) {
146-
/*
147148
local cnt = 0
148149
local icnt = 0
149150
local found = {}
@@ -243,8 +244,8 @@ static void fix_map_items(color_ostream &out, bool dry_run) {
243244
elseif should_fix then
244245
print("The problems are too severe to be fixed by this script.")
245246
end
246-
*/
247247
}
248+
*/
248249

249250
struct OccBuf {
250251
private:
@@ -269,9 +270,15 @@ struct OccBuf {
269270
return &buf[off];
270271
return nullptr;
271272
}
273+
274+
df::tile_occupancy * occ(const df::coord & pos) {
275+
return occ(pos.x, pos.y, pos.z);
276+
}
272277
};
273278

274-
static void reconcile_map_tile(color_ostream &out, df::tile_occupancy & expected_occ, df::tile_occupancy & block_occ, bool dry_run) {
279+
static void reconcile_map_tile(color_ostream &out, df::tile_occupancy & expected_occ, df::tile_occupancy & block_occ,
280+
bool dry_run, int x, int y, int z)
281+
{
275282
// clear building occupancy if there is no building there
276283
if (expected_occ.bits.building == df::tile_building_occ::None && block_occ.bits.building != df::tile_building_occ::None) {
277284
INFO(log,out).print("%s building occupancy at (%d, %d, %d)\n",
@@ -280,60 +287,63 @@ static void reconcile_map_tile(color_ostream &out, df::tile_occupancy & expected
280287
block_occ.bits.building = df::tile_building_occ::None;
281288
}
282289

283-
// check/fix unit occupancy
284-
if (occ->bits.unit || occ->bits.unit_grounded) {
285-
vector<df::unit *> units;
286-
Units::getUnitsInBox(units, pos.x, pos.y, pos.z, pos.x, pos.y, pos.z);
287-
bool found_standing_unit = false;
288-
bool found_grounded_unit = false;
289-
for (auto unit : units) {
290-
if (unit->flags1.bits.caged)
291-
continue;
292-
if (unit->flags1.bits.on_ground)
293-
found_grounded_unit = true;
294-
else
295-
found_standing_unit = true;
296-
}
297-
if (occ->bits.unit != found_standing_unit) {
298-
INFO(log,out).print("%s standing unit occupancy at (%d, %d, %d)\n",
299-
dry_run ? "would fix" : "fixing", pos.x, pos.y, pos.z);
300-
if (!dry_run)
301-
occ->bits.unit = found_standing_unit;
302-
}
303-
if (occ->bits.unit_grounded != found_grounded_unit) {
304-
INFO(log,out).print("%s grounded unit occupancy at (%d, %d, %d)\n",
305-
dry_run ? "would fix" : "fixing", pos.x, pos.y, pos.z);
306-
if (!dry_run)
307-
occ->bits.unit_grounded = found_grounded_unit;
308-
}
290+
// clear unit occupancy if there are no units there
291+
if (!expected_occ.bits.unit && block_occ.bits.unit) {
292+
INFO(log,out).print("%s standing unit occupancy at (%d, %d, %d)\n",
293+
dry_run ? "would fix" : "fixing", x, y, z);
294+
if (!dry_run)
295+
block_occ.bits.unit = false;
296+
}
297+
if (!expected_occ.bits.unit_grounded && block_occ.bits.unit_grounded) {
298+
INFO(log,out).print("%s grounded unit occupancy at (%d, %d, %d)\n",
299+
dry_run ? "would fix" : "fixing", x, y, z);
300+
if (!dry_run)
301+
block_occ.bits.unit_grounded = false;
309302
}
310303

311-
// check/fix block occupancy
312-
if (occ->bits.item != found_item) {
304+
// clear item occupancy if there are no items there
305+
if (!expected_occ.bits.item && block_occ.bits.item) {
313306
INFO(log,out).print("%s item occupancy at (%d, %d, %d)\n",
314-
dry_run ? "would fix" : "fixing", pos.x, pos.y, pos.z);
307+
dry_run ? "would fix" : "fixing", x, y, z);
315308
if (!dry_run)
316-
occ->bits.item = found_item;
309+
block_occ.bits.item = false;
317310
}
318-
319311
}
320312

321313
static void fix_map(color_ostream &out, bool dry_run) {
314+
static const uint32_t occ_mask = df::tile_occupancy::mask_building | df::tile_occupancy::mask_unit |
315+
df::tile_occupancy::mask_unit_grounded | df::tile_occupancy::mask_item;
316+
322317
OccBuf occ_buf;
323318

324319
// set expected building occupancy
325320
for (auto bld : world->buildings.all) {
326-
321+
for (int y = bld->y1; y <= bld->y2; ++y) {
322+
for (int x = bld->x1; x <= bld->x2; ++x) {
323+
if (Buildings::containsTile(bld, df::coord2d(x, y))) {
324+
if (auto occ = occ_buf.occ(x, y, bld->z))
325+
occ->bits.building = df::tile_building_occ::Impassable;
326+
}
327+
}
328+
}
327329
}
328330

329331
// set expected unit occupancy
330332
for (auto unit : world->units.active) {
331-
333+
if (unit->flags1.bits.caged)
334+
continue;
335+
if (auto occ = occ_buf.occ(unit->pos)) {
336+
occ->bits.unit = !unit->flags1.bits.on_ground;
337+
occ->bits.unit_grounded = unit->flags1.bits.on_ground;
338+
}
332339
}
333340

334341
// set expected item occupancy
335342
for (auto item : world->items.other.IN_PLAY) {
336-
343+
if (!item->flags.bits.on_ground)
344+
continue;
345+
if (auto occ = occ_buf.occ(Items::getPosition(item)))
346+
occ->bits.item = true;
337347
}
338348

339349
// check against expected occupancy and fix
@@ -352,29 +362,34 @@ static void fix_map(color_ostream &out, bool dry_run) {
352362
TRACE(log,out).print("pos out of bounds (%d, %d, %d)\n", x, y, z);
353363
continue;
354364
}
355-
reconcile_map_tile(out, *expected_occ, block->occupancy[x][y], dry_run);
365+
df::tile_occupancy &block_occ = block->occupancy[x][y];
366+
if ((expected_occ->whole & occ_mask) != (block_occ.whole & occ_mask)) {
367+
TRACE(log,out).print("reconciling occupancy at (%d, %d, %d) (%d != %d)\n",
368+
x, y, z, expected_occ->whole & occ_mask, block_occ.whole & occ_mask);
369+
reconcile_map_tile(out, *expected_occ, block_occ, dry_run, x, y, z);
370+
}
356371
}
357372
}
358373
}
359374

360-
// check/fix item membership in block item vector
361-
bool found_item = false;
362-
for (auto item : world->items.other.IN_PLAY) {
363-
if (!item->flags.bits.on_ground || item->pos != pos)
364-
continue;
365-
found_item = true;
366-
if (!dry_run) {
367-
bool inserted = false;
368-
insert_into_vector(block->items, item->id, &inserted);
369-
if (inserted) {
370-
INFO(log,out).print("fixing item membership in map block item list at (%d, %d, %d)\n",
371-
pos.x, pos.y, pos.z);
372-
}
373-
} else if (!vector_contains(block->items, item->id)) {
374-
INFO(log,out).print("would fix item membership in map block item list at (%d, %d, %d)\n",
375-
pos.x, pos.y, pos.z);
376-
}
377-
}
375+
// check/fix item membership in block item vectors
376+
// bool found_item = false;
377+
// for (auto item : world->items.other.IN_PLAY) {
378+
// if (!item->flags.bits.on_ground || item->pos != pos)
379+
// continue;
380+
// found_item = true;
381+
// if (!dry_run) {
382+
// bool inserted = false;
383+
// insert_into_vector(block->items, item->id, &inserted);
384+
// if (inserted) {
385+
// INFO(log,out).print("fixing item membership in map block item list at (%d, %d, %d)\n",
386+
// pos.x, pos.y, pos.z);
387+
// }
388+
// } else if (!vector_contains(block->items, item->id)) {
389+
// INFO(log,out).print("would fix item membership in map block item list at (%d, %d, %d)\n",
390+
// pos.x, pos.y, pos.z);
391+
// }
392+
// }
378393

379394
}
380395

plugins/lua/fix-occupancy.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ function parse_commandline(args)
2121
else
2222
fix_tile(argparse.coords(positionals[1], 'pos'), opts.dry_run)
2323
end
24+
25+
return true
2426
end
2527

2628
return _ENV

0 commit comments

Comments
 (0)