Placements API
Read the builds loaded in BuildPrint: where they are, what they want at a block, progress and materials.
BuildprintPlacements is read-only. It suits a minimap that draws the outlines of builds, a HUD that shows progress, or a storage mod that shows what a build still needs. From BuildPrint 0.1.17.
Each build has an int id that stays the same while it is loaded. A build loaded again after a restart gets a new one. Dimensions are ids like minecraft:overworld, and block states are strings like minecraft:oak_stairs[facing=east,half=bottom,shape=straight,waterlogged=false].
List the builds #
for (int id : BuildprintPlacements.ids()) {
if (!BuildprintPlacements.visible(id)) continue;
String name = BuildprintPlacements.name(id);
int[] box = BuildprintPlacements.bounds(id); // minX, minY, minZ, maxX, maxY, maxZ
double done = BuildprintPlacements.completion(id); // 0 to 1
}Ask about one block #
String dim = level.dimension().identifier().toString();
String wants = BuildprintPlacements.expectedAt(dim, x, y, z); // null: no build here
String status = BuildprintPlacements.statusAt(dim, x, y, z); // "MISSING", "CORRECT", ...Where builds overlap, one that wants a block there wins over one that wants air, the same as BuildPrint's own look-at card. The expected state is turned the way the build is turned.
| Status | Means |
|---|---|
CORRECT | The right block in the right state. |
MISSING | The build wants a block and there is air. |
WRONG_BLOCK | A different block is there. |
WRONG_STATE | The right block, turned or set differently. |
EXTRA | The build wants air and there is a block. |
UNKNOWN | Not checked yet, or its chunk was not loaded last time. |
Ask one build, now #
statusAt gives what BuildPrint saw the last time it checked the block, and picks one build where builds overlap. To decide about a single block, for example whether to break it, ask each build that covers it. statusIn checks the world right now. From BuildPrint 0.1.19.
for (int id : BuildprintPlacements.placementsAt(dim, x, y, z)) {
String status = BuildprintPlacements.statusIn(id, x, y, z);
if ("EXTRA".equals(status) || "WRONG_BLOCK".equals(status)) {
// this build doesn't want what's there
}
}statusIn gives UNKNOWN where the chunk is not loaded, and where there is nothing to check: the build wants air and there is air, or the build does not care about this block. Sign text is not compared, and a door the player is using counts as right.
Blueprint data #
snapshot(id) gives a copy of a build's blueprint, before it is turned. Changing the copy changes nothing in BuildPrint. Captures use the same shape, and previews take it. It is a Map<String, Object> with these keys. From BuildPrint 0.1.19.
| Key | Type | What it holds |
|---|---|---|
name, author | String | Empty when unknown. |
size | int[] | {width, height, length}. |
palette | String[] | Block state strings. |
blocks | int[] | One palette index per block. X fastest, then Z, then Y: (y * length + z) * width + x. |
blockEntities | Map<Integer, String> | Block index to SNBT: chest contents, sign text. |
entities | String[] | SNBT per entity, with Pos relative to the blueprint and Rotation. |
regions | int[] | Boxes in the blueprint, 6 numbers each, inclusive. A loaded build is one box, because the regions of a .litematic are merged when it loads. |
Be told about changes #
BuildprintPlacements.listen("mymod", (event, id) -> {
switch (event) {
case "added" -> addMarker(id); // loaded, or restored on joining a world
case "removed" -> removeMarker(id);
case "moved" -> moveMarker(id); // moved, turned or flipped
}
});Events come on the client thread, at the end of the tick they happened in. One listener per owner: a second call replaces the first. unlisten(owner) stops it.
Reference #
| BuildprintPlacements | What it does |
|---|---|
ids() | The loaded builds, oldest first. |
exists(int id) | Whether that build is loaded. |
name(int id) / owner(int id) | Its name, and the mod that keeps it through BuildprintBlueprints. owner is null for a player's own build. |
dimension(int id) / visible(int id) | Where it is, and whether it is drawn right now. |
origin(int id) | {x, y, z} of the placement. |
rotation(int id) / flipped(int id) | Clockwise degrees (0, 90, 180, 270), and whether it is mirrored. |
orientationFixed(int id) | Whether the player cannot turn or flip it. |
size(int id) | {width, height, length} before turning. |
bounds(int id) | {minX, minY, minZ, maxX, maxY, maxZ} in the world, inclusive. |
version(int id) | Changes when the build is moved, turned or flipped. |
placementAt(String dim, int x, int y, int z) | The visible build covering a block, or -1. |
expectedAt(String dim, int x, int y, int z) | The block state the build wants there, or null. |
statusAt(String dim, int x, int y, int z) | How the block compares, or null. |
counts(int id) | {required, placed, missing, wrongBlock, wrongState, extra, unknown}. |
completion(int id) / fullyChecked(int id) | Progress from 0 to 1, and whether every block was checked once. |
materials(int id) | Item id to {required, placed, stillNeeded}, in the order of the material list. Includes container contents and extras such as dyes for signs. |
listen(String owner, BiConsumer<String, Integer> listener) / unlisten(String owner) | Get added, removed and moved events, or stop. |
snapshot(int id) | The whole blueprint as plain data, before turning. Null for builds over 67,108,864 blocks. Since 0.1.19. |
placementsAt(String dim, int x, int y, int z) | Every visible build covering a block, oldest first. Since 0.1.19. |
expectedIn(int id, int x, int y, int z) | As expectedAt, for one build, shown or not. Since 0.1.19. |
statusIn(int id, int x, int y, int z) | As statusAt, for one build, shown or not, checked against the world now. Since 0.1.19. |
Something missing or wrong on this page? Say so on Discord.