Search in sources :

Example 1 with Block

use of org.pepsoft.minecraft.Block in project WorldPainter by Captain-Chaos.

the class WPObjectExporter method isRoom.

/**
 * Checks block by block and taking the object's collision mode attributes
 * and other rules into account whether it can be placed at a particular
 * location. This is a slow operation, so use
 * {@link #isSane(WPObject, int, int, int, int)} first to weed out objects
 * for which this check does not even apply.
 *
 * @return <code>true</code> if the object may be placed at the specified
 *     location according to its collision mode attributes.
 */
public static boolean isRoom(final MinecraftWorld world, final Dimension dimension, final WPObject object, final int x, final int y, final int z, final Placement placement) {
    final Point3i dimensions = object.getDimensions();
    final Point3i offset = object.getOffset();
    final int collisionMode = object.getAttribute(ATTRIBUTE_COLLISION_MODE), maxHeight = world.getMaxHeight();
    final boolean allowConnectingBlocks = false, bottomlessWorld = dimension.isBottomless();
    // Check if the object fits vertically
    if (((long) z + dimensions.z - 1 + offset.z) >= world.getMaxHeight()) {
        if (logger.isTraceEnabled()) {
            logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it does not fit below the map height of " + world.getMaxHeight());
        }
        return false;
    }
    if (((long) z + dimensions.z - 1 + offset.z) < 0) {
        if (logger.isTraceEnabled()) {
            logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it is entirely below the bedrock");
        }
        return false;
    }
    if ((placement == Placement.ON_LAND) && (collisionMode != COLLISION_MODE_NONE)) {
        // Check block by block whether there is room
        for (int dx = 0; dx < dimensions.x; dx++) {
            for (int dy = 0; dy < dimensions.y; dy++) {
                final int worldX = x + dx + offset.x, worldY = y + dy + offset.y;
                for (int dz = 0; dz < dimensions.z; dz++) {
                    if (object.getMask(dx, dy, dz)) {
                        final Block objectBlock = object.getMaterial(dx, dy, dz).block;
                        if (!objectBlock.veryInsubstantial) {
                            final int worldZ = z + dz + offset.z;
                            if (worldZ < (bottomlessWorld ? 0 : 1)) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it extends below the bottom of the map");
                                }
                                return false;
                            } else if (worldZ >= maxHeight) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it extends above the top of the map");
                                }
                                return false;
                            } else if (worldZ > dimension.getIntHeightAt(worldX, worldY)) {
                                if ((collisionMode == COLLISION_MODE_ALL) ? (!AIR_AND_FLUIDS.contains(world.getBlockTypeAt(worldX, worldY, worldZ))) : (!BLOCKS[world.getBlockTypeAt(worldX, worldY, worldZ)].veryInsubstantial)) {
                                    // there is no room for this object
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " due to collision with existing above ground block of type " + BLOCKS[world.getBlockTypeAt(worldX, worldY, worldZ)]);
                                    }
                                    return false;
                                } else if ((!allowConnectingBlocks) && wouldConnect(world, worldX, worldY, worldZ, objectBlock.id)) {
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it would cause a connecting block");
                                    }
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
        }
    } else if (placement == Placement.FLOATING) {
        // with the floor
        for (int dx = 0; dx < dimensions.x; dx++) {
            for (int dy = 0; dy < dimensions.y; dy++) {
                final int worldX = x + dx + offset.x, worldY = y + dy + offset.y;
                final int terrainHeight = dimension.getIntHeightAt(worldX, worldY);
                for (int dz = 0; dz < dimensions.z; dz++) {
                    if (object.getMask(dx, dy, dz)) {
                        final Block objectBlock = object.getMaterial(dx, dy, dz).block;
                        if (!objectBlock.veryInsubstantial) {
                            final int worldZ = z + dz + offset.z;
                            if (worldZ < (bottomlessWorld ? 0 : 1)) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it extends below the bottom of the map");
                                }
                                return false;
                            } else if (worldZ >= maxHeight) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it extends above the top of the map");
                                }
                                return false;
                            } else if (worldZ <= terrainHeight) {
                                // the floor
                                if (logger.isTraceEnabled()) {
                                    logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " due to collision with floor");
                                }
                                return false;
                            } else if (collisionMode != COLLISION_MODE_NONE) {
                                if ((collisionMode == COLLISION_MODE_ALL) ? (!AIR_AND_FLUIDS.contains(world.getBlockTypeAt(worldX, worldY, worldZ))) : (!BLOCKS[world.getBlockTypeAt(worldX, worldY, worldZ)].veryInsubstantial)) {
                                    // world; there is no room for this object
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " due to collision with existing above ground block of type " + BLOCK_TYPE_NAMES[world.getBlockTypeAt(worldX, worldY, worldZ)]);
                                    }
                                    return false;
                                } else if ((!allowConnectingBlocks) && wouldConnect(world, worldX, worldY, worldZ, objectBlock.id)) {
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("No room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement + " because it would cause a connecting block");
                                    }
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    if (logger.isTraceEnabled()) {
        logger.trace("There is room for object " + object.getName() + " @ " + x + "," + y + "," + z + " with placement " + placement);
    }
    return true;
}
Also used : Point3i(javax.vecmath.Point3i) Block(org.pepsoft.minecraft.Block)

Aggregations

Point3i (javax.vecmath.Point3i)1 Block (org.pepsoft.minecraft.Block)1