package org.pepsoft.worldpainter.layers.bo2; import org.pepsoft.minecraft.Material; import org.pepsoft.minecraft.TileEntity; import javax.vecmath.Point3i; import java.util.Arrays; import java.util.Collections; import java.util.Random; import java.util.Set; import java.util.stream.Collectors; /** * Created by pepijn on 25-7-15. */ public class Bo3BlockSpec extends Bo2BlockSpec { public Bo3BlockSpec(Point3i coords, Material material, TileEntity tileEntity) { super(coords, material, null); this.tileEntity = tileEntity; if (tileEntity != null) { tileEntity.setX(coords.x); tileEntity.setY(coords.z); tileEntity.setZ(coords.y); } randomBlocks = null; } public Bo3BlockSpec(Point3i coords, RandomBlock[] randomBlocks) { super(coords, null, null); tileEntity = null; this.randomBlocks = randomBlocks; Arrays.stream(randomBlocks) .filter(b -> b.tileEntity != null) .forEach(b -> { b.tileEntity.setX(coords.x); b.tileEntity.setY(coords.z); b.tileEntity.setZ(coords.y); }); } /** * Gets all tile entities contained in this block. Note that since bo3 * objects can contain random blocks, which can be tile entities with * different contents, this collection can contain multiple overlapping * tile entities with the same coordinates. Hopefully WorldPainter's post * processing will deal with that correctly. TODO: does it? * * @return All tile entities contained in this object, or an empty * collection if there are none. */ public Set<TileEntity> getTileEntities() { if (randomBlocks != null) { return Arrays.stream(randomBlocks) .filter(b -> b.tileEntity != null) .map(b -> b.tileEntity) .collect(Collectors.toSet()); } else if (tileEntity != null) { return Collections.singleton(tileEntity); } else { return Collections.emptySet(); } } // Bo2BlockSpec @Override public Material getMaterial() { if (randomBlocks != null) { for (RandomBlock randomBlock: randomBlocks) { if ((randomBlock.chance >= 100) || (RANDOM.nextInt(100) < randomBlock.chance)) { return randomBlock.material; } } // The spec is not really clear what to do if this happens: return randomBlocks[randomBlocks.length - 1].material; } else { return super.getMaterial(); } } private final TileEntity tileEntity; private final RandomBlock[] randomBlocks; private static final Random RANDOM = new Random(); private static final long serialVersionUID = 1L; public static class RandomBlock { RandomBlock(Material material, TileEntity tileEntity, int chance) { this.material = material; this.tileEntity = tileEntity; this.chance = chance; } final Material material; final TileEntity tileEntity; final int chance; } }