use of org.pepsoft.minecraft.TileEntity in project WorldPainter by Captain-Chaos.
the class RotatedObject method getTileEntities.
@Override
public List<TileEntity> getTileEntities() {
if (steps == 0) {
return object.getTileEntities();
} else {
List<TileEntity> objectTileEntities = object.getTileEntities();
if (objectTileEntities != null) {
List<TileEntity> tileEntities = new ArrayList<>(objectTileEntities.size());
for (TileEntity objectTileEntity : objectTileEntities) {
TileEntity tileEntity = (TileEntity) objectTileEntity.clone();
switch(steps) {
case 1:
tileEntity.setX(dimensions.x - objectTileEntity.getZ() - 1);
tileEntity.setZ(objectTileEntity.getX());
break;
case 2:
tileEntity.setX(dimensions.x - objectTileEntity.getX() - 1);
tileEntity.setZ(dimensions.y - objectTileEntity.getZ() - 1);
break;
case 3:
tileEntity.setX(objectTileEntity.getZ());
tileEntity.setZ(dimensions.y - objectTileEntity.getX() - 1);
break;
default:
throw new InternalError();
}
tileEntities.add(tileEntity);
}
return tileEntities;
} else {
return null;
}
}
}
use of org.pepsoft.minecraft.TileEntity in project WorldPainter by Captain-Chaos.
the class WPObjectExporter method renderObject.
/**
* Export an object to the world, optionally taking into account the blocks
* that are already there.
*
* @param world The Minecraft world to which to export the object.
* @param dimension The dimension corresponding to the exported world, used
* to determine the terrain height.
* @param object The object to export.
* @param x The X coordinate at which to export the object.
* @param y The Y coordinate at which to export the object.
* @param z The Z coordinate at which to export the object.
* @param obliterate When <code>true</code>, all blocks of the object are
* placed regardless of what is already there. When <code>false</code>,
* rules are followed and some or all blocks may not be placed,
* depending on what is already there.
*/
public static void renderObject(MinecraftWorld world, Dimension dimension, WPObject object, int x, int y, int z, boolean obliterate) {
final Point3i dim = object.getDimensions();
final Point3i offset = object.getOffset();
final int undergroundMode = object.getAttribute(ATTRIBUTE_UNDERGROUND_MODE);
final int leafDecayMode = object.getAttribute(ATTRIBUTE_LEAF_DECAY_MODE);
final boolean bottomless = dimension.isBottomless();
final int[] replaceBlockIds = object.getAttribute(ATTRIBUTE_REPLACE_WITH_AIR);
final boolean replaceBlocks = replaceBlockIds != null;
final boolean extendFoundation = object.getAttribute(ATTRIBUTE_EXTEND_FOUNDATION);
if ((z + offset.z + dim.z - 1) >= world.getMaxHeight()) {
// Object doesn't fit in the world vertically
return;
}
// System.out.println("Object dimensions: " + dim + ", origin: " + orig);
for (int dx = 0; dx < dim.x; dx++) {
for (int dy = 0; dy < dim.y; dy++) {
final int worldX = x + dx + offset.x;
final int worldY = y + dy + offset.y;
final int terrainHeight = dimension.getIntHeightAt(worldX, worldY);
for (int dz = 0; dz < dim.z; dz++) {
if (object.getMask(dx, dy, dz)) {
final Material objectMaterial = object.getMaterial(dx, dy, dz);
final Material finalMaterial = (replaceBlocks && (objectMaterial.blockType == replaceBlockIds[0]) && (objectMaterial.data == replaceBlockIds[1])) ? Material.AIR : objectMaterial;
final int worldZ = z + dz + offset.z;
if ((bottomless || obliterate) ? (worldZ < 0) : (worldZ < 1)) {
continue;
} else if (obliterate) {
placeBlock(world, worldX, worldY, worldZ, finalMaterial, leafDecayMode);
} else {
final int existingBlockType = world.getBlockTypeAt(worldX, worldY, worldZ);
if (worldZ <= terrainHeight) {
switch(undergroundMode) {
case COLLISION_MODE_ALL:
// Replace every block
placeBlock(world, worldX, worldY, worldZ, finalMaterial, leafDecayMode);
break;
case COLLISION_MODE_SOLID:
// Only replace if object block is solid
if (!objectMaterial.block.veryInsubstantial) {
placeBlock(world, worldX, worldY, worldZ, finalMaterial, leafDecayMode);
}
break;
case COLLISION_MODE_NONE:
// Only replace less solid blocks
if (BLOCKS[existingBlockType].veryInsubstantial) {
placeBlock(world, worldX, worldY, worldZ, finalMaterial, leafDecayMode);
}
break;
}
} else {
// Above ground only replace less solid blocks
if (BLOCKS[existingBlockType].veryInsubstantial) {
placeBlock(world, worldX, worldY, worldZ, finalMaterial, leafDecayMode);
}
}
}
if (extendFoundation && (dz == 0) && (terrainHeight != -1) && (worldZ > terrainHeight) && (!finalMaterial.block.veryInsubstantial)) {
int legZ = worldZ - 1;
while ((legZ >= 0) && world.getMaterialAt(worldX, worldY, legZ).block.veryInsubstantial) {
placeBlock(world, worldX, worldY, legZ, finalMaterial, leafDecayMode);
legZ--;
}
}
}
}
}
}
List<Entity> entities = object.getEntities();
if (entities != null) {
for (Entity entity : entities) {
double[] pos = entity.getPos();
double entityX = x + pos[0] + offset.x, entityY = y + pos[2] + offset.y, entityZ = z + pos[1] + offset.z;
if ((entityZ < 0) || (entityY > (world.getMaxHeight() - 1))) {
if (logger.isTraceEnabled()) {
logger.trace("NOT adding entity " + entity.getId() + " @ " + entityX + "," + entityY + "," + entityZ + " because z coordinate is out of range!");
}
} else {
if (logger.isTraceEnabled()) {
logger.trace("Adding entity " + entity.getId() + " @ " + entityX + "," + entityY + "," + entityZ);
}
// Make sure each entity has a unique ID, otherwise
// Minecraft will see them all as duplicates and remove
// them:
entity.setUUID(UUID.randomUUID());
world.addEntity(entityX, entityY, entityZ, entity);
}
}
}
List<TileEntity> tileEntities = object.getTileEntities();
if (tileEntities != null) {
for (TileEntity tileEntity : tileEntities) {
final int tileEntityX = x + tileEntity.getX() + offset.x, tileEntityY = y + tileEntity.getZ() + offset.y, tileEntityZ = z + tileEntity.getY() + offset.z;
final String entityId = tileEntity.getId();
if ((tileEntityZ < 0) || (tileEntityZ >= world.getMaxHeight())) {
if (logger.isTraceEnabled()) {
logger.trace("NOT adding tile entity " + entityId + " @ " + tileEntityX + "," + tileEntityY + "," + tileEntityZ + " because z coordinate is out of range!");
}
} else {
final int existingBlockType = world.getBlockTypeAt(tileEntityX, tileEntityY, tileEntityZ);
if (!TILE_ENTITY_MAP.containsKey(entityId)) {
if (logger.isTraceEnabled()) {
logger.trace("Adding unknown tile entity " + entityId + " @ " + tileEntityX + "," + tileEntityY + "," + tileEntityZ + " (block type: " + BLOCK_TYPE_NAMES[existingBlockType] + "; not able to detect whether the block type is correct; map may cause errors!)");
}
world.addTileEntity(tileEntityX, tileEntityY, tileEntityZ, tileEntity);
} else if (TILE_ENTITY_MAP.get(entityId).contains(existingBlockType)) {
if (logger.isTraceEnabled()) {
logger.trace("Adding tile entity " + entityId + " @ " + tileEntityX + "," + tileEntityY + "," + tileEntityZ + " (block type: " + BLOCK_TYPE_NAMES[existingBlockType] + ")");
}
world.addTileEntity(tileEntityX, tileEntityY, tileEntityZ, tileEntity);
} else {
// the world limits)
if (logger.isTraceEnabled()) {
logger.trace("NOT adding tile entity " + entityId + " @ " + tileEntityX + "," + tileEntityY + "," + tileEntityZ + " because the block there is not a (or not the same) tile entity: " + BLOCK_TYPE_NAMES[existingBlockType] + "!");
}
}
}
}
}
}
use of org.pepsoft.minecraft.TileEntity in project WorldPainter by Captain-Chaos.
the class Bo3Object method load.
/**
* Load a custom object in bo3 format from a file.
*
* @param objectName The name of the object.
* @param file The file from which to load the object.
* @return A new <code>Bo3Object</code> containing the contents of the
* specified file.
* @throws IOException If an I/O error occurred while reading the file.
*/
public static Bo3Object load(String objectName, File file) throws IOException {
try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("US-ASCII")))) {
Map<String, String> properties = new HashMap<>();
Map<Point3i, Bo3BlockSpec> blocks = new HashMap<>();
String line;
int lowestX = Integer.MAX_VALUE, highestX = Integer.MIN_VALUE;
int lowestY = Integer.MAX_VALUE, highestY = Integer.MIN_VALUE;
int lowestZ = Integer.MAX_VALUE, highestZ = Integer.MIN_VALUE;
while ((line = in.readLine()) != null) {
line = line.trim();
if (line.isEmpty() || line.startsWith("#")) {
continue;
} else if (line.startsWith("Block")) {
// Block spec
Deque<String> args = getArgs(line);
int x = Integer.parseInt(args.pop());
int z = Integer.parseInt(args.pop());
int y = Integer.parseInt(args.pop());
if (x < lowestX) {
lowestX = x;
}
if (x > highestX) {
highestX = x;
}
if (y < lowestY) {
lowestY = y;
}
if (y > highestY) {
highestY = y;
}
if (z < lowestZ) {
lowestZ = z;
}
if (z > highestZ) {
highestZ = z;
}
Material material = decodeMaterial(args.pop());
TileEntity tileEntity = null;
if (!args.isEmpty()) {
tileEntity = loadTileEntity(file, args.pop());
}
Point3i coords = new Point3i(x, y, z);
blocks.put(coords, new Bo3BlockSpec(coords, material, tileEntity));
} else if (line.startsWith("RandomBlock")) {
// Random block spec
Deque<String> args = getArgs(line);
int x = Integer.parseInt(args.pop());
int z = Integer.parseInt(args.pop());
int y = Integer.parseInt(args.pop());
if (x < lowestX) {
lowestX = x;
}
if (x > highestX) {
highestX = x;
}
if (y < lowestY) {
lowestY = y;
}
if (y > highestY) {
highestY = y;
}
if (z < lowestZ) {
lowestZ = z;
}
if (z > highestZ) {
highestZ = z;
}
List<Bo3BlockSpec.RandomBlock> randomBlocks = new ArrayList<>();
do {
Material material = decodeMaterial(args.pop());
String nbtOrChance = args.pop();
TileEntity tileEntity = null;
int chance;
try {
chance = Integer.parseInt(nbtOrChance);
} catch (NumberFormatException e) {
tileEntity = loadTileEntity(file, nbtOrChance);
chance = Integer.parseInt(args.pop());
}
randomBlocks.add(new Bo3BlockSpec.RandomBlock(material, tileEntity, chance));
} while (!args.isEmpty());
Point3i coords = new Point3i(x, y, z);
blocks.put(coords, new Bo3BlockSpec(coords, randomBlocks.toArray(new Bo3BlockSpec.RandomBlock[randomBlocks.size()])));
} else if (line.startsWith("BlockCheck") || line.startsWith("LightCheck") || line.startsWith("Branch") || line.startsWith("WeightedBranch")) {
logger.warn("Ignoring unsupported bo3 feature " + line);
} else {
int p = line.indexOf(':');
if (p != -1) {
properties.put(line.substring(0, p).trim(), line.substring(p + 1).trim());
} else {
logger.warn("Ignoring unrecognised line: " + line);
}
}
}
if (blocks.isEmpty()) {
throw new IOException("No blocks found in the file; is this a bo3 object?");
}
Map<String, Serializable> attributes = new HashMap<>(Collections.singletonMap(ATTRIBUTE_FILE.key, file));
return new Bo3Object(objectName, properties, blocks, new Point3i(-lowestX, -lowestY, -lowestZ), new Point3i(highestX - lowestX + 1, highestY - lowestY + 1, highestZ - lowestZ + 1), attributes);
}
}
use of org.pepsoft.minecraft.TileEntity in project WorldPainter by Captain-Chaos.
the class MirroredObject method getTileEntities.
@Override
public List<TileEntity> getTileEntities() {
List<TileEntity> objectTileEntities = object.getTileEntities();
if (objectTileEntities != null) {
List<TileEntity> tileEntities = new ArrayList<>(objectTileEntities.size());
for (TileEntity objectTileEntity : objectTileEntities) {
TileEntity tileEntity = (TileEntity) objectTileEntity.clone();
if (mirrorYAxis) {
tileEntity.setZ(dimensions.y - objectTileEntity.getZ() - 1);
} else {
tileEntity.setX(dimensions.x - objectTileEntity.getX() - 1);
}
tileEntities.add(tileEntity);
}
return tileEntities;
} else {
return null;
}
}
Aggregations