use of org.pepsoft.minecraft.Material 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.Material in project WorldPainter by Captain-Chaos.
the class Structure method load.
public static Structure load(String objectName, InputStream inputStream, MCInterface mcInterface) throws IOException {
CompoundTag root;
try (NBTInputStream in = new NBTInputStream(new GZIPInputStream(new BufferedInputStream(inputStream)))) {
root = (CompoundTag) in.readTag();
}
// Load the palette
ListTag paletteTag = (ListTag) root.getTag("palette");
Material[] palette = new Material[paletteTag.getValue().size()];
for (int i = 0; i < palette.length; i++) {
palette[i] = mcInterface.decodeStructureMaterial((CompoundTag) paletteTag.getValue().get(i));
}
// Load the blocks
Map<Point3i, Material> blocks = new HashMap<>();
ListTag blocksTag = (ListTag) root.getTag("blocks");
for (Tag tag : blocksTag.getValue()) {
CompoundTag blockTag = (CompoundTag) tag;
List<Tag> posTags = ((ListTag) blockTag.getTag("pos")).getValue();
blocks.put(new Point3i(((IntTag) posTags.get(0)).getValue(), ((IntTag) posTags.get(2)).getValue(), ((IntTag) posTags.get(1)).getValue()), palette[((IntTag) blockTag.getTag("state")).getValue()]);
}
// Remove palette and blocks from the tag so we don't waste space
root.setTag("palette", null);
root.setTag("blocks", null);
return new Structure(root, objectName, blocks);
}
use of org.pepsoft.minecraft.Material in project WorldPainter by Captain-Chaos.
the class JungleTree method renderBranch.
protected void renderBranch(int x, int y, int height, int size, float angle, MinecraftWorld world, Random random) {
int l = (int) (size / 5f + 0.5f);
Material branchMaterial, capMaterial;
if ((trunkMaterial.blockType == BLK_WOOD) || (trunkMaterial.blockType == BLK_WOOD2)) {
branchMaterial = ((angle < (0.25 * Math.PI)) || ((angle > (0.75 * Math.PI)) && (angle < (1.25 * Math.PI))) || (angle > (1.75 * Math.PI))) ? Material.get(trunkMaterial.blockType, (trunkMaterial.data & 0x3) | 0x8) : Material.get(trunkMaterial.blockType, (trunkMaterial.data & 0x3) | 0x4);
capMaterial = getCapMaterial();
} else {
branchMaterial = capMaterial = trunkMaterial;
}
float slope = random.nextFloat() / 10 - 0.5f;
for (int i = 1; i < l; i++) {
int dx = (int) (Math.sin(angle) * i + 0.5f);
int dy = (int) (Math.cos(angle) * i + 0.5f);
int dz = (int) (i * slope);
if (!BLOCKS[world.getBlockTypeAt(x + dx, y + dy, height + size + dz + 1)].veryInsubstantial) {
continue;
}
world.setMaterialAt(x + dx, y + dy, height + size + dz, (i < (l - 1)) ? branchMaterial : capMaterial);
if (random.nextInt(25) == 0) {
world.setMaterialAt(x + dx, y + dy, height + size + dz + 1, random.nextBoolean() ? RED_MUSHROOM : BROWN_MUSHROOM);
}
if (((i > 1) && (((i - 1) % 3) == 0)) || (i == (l - 1))) {
renderCanopy(x + dx, y + dy, height + dz, size, world, random);
}
}
}
use of org.pepsoft.minecraft.Material in project WorldPainter by Captain-Chaos.
the class Tile3DRenderer method render.
public BufferedImage render(Tile tile) {
// System.out.println("Rendering tile " + tile);
tileRenderer.setTile(tile);
tileRenderer.renderTile(tileImgBuffer, 0, 0);
// Terrain subSurfaceMaterial = dimension.getSubsurfaceMaterial();
final long seed = dimension.getSeed();
final boolean coverSteepTerrain = dimension.isCoverSteepTerrain();
final int tileOffsetX = tile.getX() * TILE_SIZE, tileOffsetY = tile.getY() * TILE_SIZE;
int currentColour = -1;
final int imgWidth = TILE_SIZE * 2;
final int imgHeight = TILE_SIZE + maxHeight - 1;
final int maxZ = maxHeight - 1;
final BufferedImage img = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
final Graphics2D g2 = img.createGraphics();
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
for (int x = 0; x < TILE_SIZE; x++) {
for (int y = 0; y < TILE_SIZE; y++) {
// Coordinates of the block in the world
final int xInTile, yInTile;
switch(rotation) {
case 0:
xInTile = x;
yInTile = y;
break;
case 1:
xInTile = y;
yInTile = TILE_SIZE - 1 - x;
break;
case 2:
xInTile = TILE_SIZE - 1 - x;
yInTile = TILE_SIZE - 1 - y;
break;
case 3:
xInTile = TILE_SIZE - 1 - y;
yInTile = x;
break;
default:
throw new IllegalArgumentException();
}
if (tile.getBitLayerValue(org.pepsoft.worldpainter.layers.Void.INSTANCE, xInTile, yInTile) || tile.getBitLayerValue(NotPresent.INSTANCE, xInTile, yInTile)) {
continue;
}
final int blockX = tileOffsetX + xInTile, blockY = tileOffsetY + yInTile;
final int terrainHeight = tile.getIntHeight(xInTile, yInTile);
final int fluidLevel = tile.getWaterLevel(xInTile, yInTile);
final boolean floodWithLava;
if (fluidLevel > terrainHeight) {
floodWithLava = tile.getBitLayerValue(FloodWithLava.INSTANCE, xInTile, yInTile);
} else {
floodWithLava = false;
}
// Image coordinates
final float imgX = TILE_SIZE + x - y - 0.5f, imgY = (x + y) / 2f + maxHeight - 0.5f;
// System.out.println(blockX + ", " + blockY + " -> " + blockXTranslated + ", " + blockYTranslated + " -> " + imgX + ", " + imgY);
int subsurfaceHeight = Math.max(terrainHeight - dimension.getTopLayerDepth(blockX, blockY, terrainHeight), 0);
if (coverSteepTerrain) {
subsurfaceHeight = Math.min(subsurfaceHeight, Math.min(Math.min(dimension.getIntHeightAt(blockX - 1, blockY, Integer.MAX_VALUE), dimension.getIntHeightAt(blockX + 1, blockY, Integer.MAX_VALUE)), Math.min(dimension.getIntHeightAt(blockX, blockY - 1, Integer.MAX_VALUE), dimension.getIntHeightAt(blockX, blockY + 1, Integer.MAX_VALUE))));
}
int colour = colourScheme.getColour(BLK_STONE);
if (colour != currentColour) {
g2.setColor(new Color(colour));
currentColour = colour;
}
if (subsurfaceHeight > 0) {
g2.fill(new Rectangle2D.Float(imgX, imgY - subsurfaceHeight, 2, subsurfaceHeight));
}
// for (int z = 0; z <= subsurfaceHeight; z++) {
// colour = colourScheme.getColour(subSurfaceMaterial.getMaterial(seed, blockX, blockY, z, terrainHeight));
// if (colour != currentColour) {
// // g2.setColor(new Color(ColourUtils.multiply(colour, brightenAmount)));
// g2.setColor(new Color(colour));
// currentColour = colour;
// }
// g2.draw(new Line2D.Float(imgX, imgY - z, imgX + 1, imgY - z));
// }
// Do this per block because they might have different
// colours
final Terrain terrain = tile.getTerrain(xInTile, yInTile);
Material nextMaterial = terrain.getMaterial(seed, blockX, blockY, subsurfaceHeight + 1, terrainHeight);
for (int z = subsurfaceHeight + 1; z <= terrainHeight - 1; z++) {
Material material = nextMaterial;
if (z < maxZ) {
nextMaterial = terrain.getMaterial(seed, blockX, blockY, z + 1, terrainHeight);
if (!nextMaterial.block.veryInsubstantial) {
// Block above is solid
if ((material == Material.GRASS) || (material == Material.MYCELIUM) || (material == Material.TILLED_DIRT)) {
material = Material.DIRT;
}
}
}
colour = colourScheme.getColour(material);
if (colour != currentColour) {
// g2.setColor(new Color(ColourUtils.multiply(colour, brightenAmount)));
g2.setColor(new Color(colour));
currentColour = colour;
}
g2.draw(new Line2D.Float(imgX, imgY - z, imgX + 1, imgY - z));
}
colour = tileImgBuffer.getRGB(xInTile, yInTile);
if (colour != currentColour) {
g2.setColor(new Color(colour));
currentColour = colour;
}
g2.draw(new Line2D.Float(imgX, imgY - terrainHeight, imgX + 1, imgY - terrainHeight));
if (fluidLevel > terrainHeight) {
colour = colourScheme.getColour(floodWithLava ? BLK_LAVA : BLK_WATER);
// currentColour = 0x80000000 | ColourUtils.multiply(colour, brightenAmount);
currentColour = 0x80000000 | colour;
g2.setColor(new Color(currentColour, true));
boolean ice = (!floodWithLava) && tile.getBitLayerValue(Frost.INSTANCE, xInTile, yInTile);
for (int z = terrainHeight + 1; z <= fluidLevel; z++) {
if ((z == fluidLevel) && ice) {
colour = colourScheme.getColour(BLK_ICE);
g2.setColor(new Color(colour));
currentColour = colour;
}
g2.draw(new Line2D.Float(imgX, imgY - z, imgX + 1, imgY - z));
}
}
}
}
} finally {
g2.dispose();
}
return img;
}
use of org.pepsoft.minecraft.Material in project WorldPainter by Captain-Chaos.
the class MixedMaterial method getMaterial.
public Material getMaterial(long seed, int x, int y, int z) {
switch(mode) {
case SIMPLE:
return simpleMaterial;
case NOISE:
return materials[random.nextInt(1000)];
case BLOBS:
double xx = x / Constants.TINY_BLOBS, yy = y / Constants.TINY_BLOBS, zz = z / Constants.TINY_BLOBS;
if (seed + 1 != noiseGenerators[0].getSeed()) {
for (int i = 0; i < noiseGenerators.length; i++) {
noiseGenerators[i].setSeed(seed + i + 1);
}
}
Material material = sortedRows[sortedRows.length - 1].material;
for (int i = noiseGenerators.length - 1; i >= 0; i--) {
final float rowScale = sortedRows[i].scale * this.scale;
if (noiseGenerators[i].getPerlinNoise(xx / rowScale, yy / rowScale, zz / rowScale) >= sortedRows[i].chance) {
material = sortedRows[i].material;
}
}
return material;
case LAYERED:
float fZ = z;
if (layerNoiseheightMap != null) {
if (layerNoiseheightMap.getSeed() != seed) {
layerNoiseheightMap.setSeed(seed);
}
fZ += layerNoiseheightMap.getValue(x, y, z) - layerNoiseOffset;
}
if (repeat) {
if (layerXSlope != 0.0) {
fZ += layerXSlope * x;
}
if (layerYSlope != 0.0) {
fZ += layerYSlope * y;
}
return materials[Math.floorMod((int) (fZ + 0.5f), materials.length)];
} else {
final int iZ = (int) (fZ + 0.5f);
if (iZ < 0) {
return materials[0];
} else if (iZ >= materials.length) {
return materials[materials.length - 1];
} else {
return materials[iZ];
}
}
default:
throw new InternalError();
}
}
Aggregations