use of com.ferreusveritas.dynamictrees.util.BlockBounds in project DynamicTrees by DynamicTreesTeam.
the class FeatureGenHugeMushroom method generate.
@Override
public boolean generate(World world, BlockPos rootPos, Species species, Biome biome, Random random, int radius, SafeChunkBounds safeBounds) {
BlockPos genPos = rootPos.up();
int height = getMushroomHeight(world, rootPos, biome, random, radius, safeBounds);
IBlockState soilState = world.getBlockState(rootPos);
if (species.isAcceptableSoilForWorldgen(world, rootPos, soilState)) {
Block mushroomBlock = this.mushroomType;
if (mushroomBlock == null) {
mushroomBlock = random.nextBoolean() ? Blocks.BROWN_MUSHROOM_BLOCK : Blocks.RED_MUSHROOM_BLOCK;
}
SimpleVoxmap capMap = getCapForHeight(mushroomBlock, height);
// Determine the cap position(top block of mushroom cap)
BlockPos capPos = genPos.up(height - 1);
// Get a bounding box for the entire cap
BlockBounds capBounds = capMap.getBounds().move(capPos);
if (safeBounds.inBounds(capBounds, true)) {
// Check if there's room for a mushroom cap and stem
for (MutableBlockPos mutPos : Iterables.concat(BlockPos.getAllInBoxMutable(BlockPos.ORIGIN.down(capMap.getLenY()), BlockPos.ORIGIN.down(height - 1)), capMap.getAllNonZero())) {
// System.out.println(mutPos);
BlockPos dPos = mutPos.add(capPos);
IBlockState state = world.getBlockState(dPos);
if (!state.getBlock().canBeReplacedByLeaves(state, world, dPos) || !state.getBlock().isReplaceable(world, dPos)) {
return false;
}
}
// Construct the mushroom cap from the voxel map
for (Cell cell : capMap.getAllNonZeroCells()) {
BlockHugeMushroom.EnumType mushroomType = BlockHugeMushroom.EnumType.byMetadata(cell.getValue());
world.setBlockState(capPos.add(cell.getPos()), mushroomBlock.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, mushroomType));
}
// Construct the stem
int stemLen = height - capMap.getLenY();
IBlockState stemBlock = mushroomBlock.getDefaultState().withProperty(BlockHugeMushroom.VARIANT, BlockHugeMushroom.EnumType.STEM);
for (int y = 0; y < stemLen; y++) {
world.setBlockState(genPos.up(y), stemBlock);
}
return true;
}
}
return false;
}
use of com.ferreusveritas.dynamictrees.util.BlockBounds in project DynamicTrees by DynamicTreesTeam.
the class EntityFallingTree method buildClient.
public void buildClient() {
NBTTagCompound tag = getVoxelData();
if (tag.hasKey("species")) {
setupFromNBT(tag);
clientBuilt = true;
} else {
System.out.println("Error: No species tag has been set");
}
BlockBounds renderBounds = new BlockBounds(destroyData.cutPos);
if (destroyType == DestroyType.VOID) {
// Void usually occurs during worldgen. So we need to ensure that what we're breaking is still tree stuff
for (BlockPos absPos : Iterables.concat(destroyData.getPositions(PosType.BRANCHES), destroyData.getPositions(PosType.LEAVES))) {
IBlockState state = world.getBlockState(absPos);
if (TreeHelper.isTreePart(state)) {
// The client needs to set it's blocks to air
world.setBlockState(absPos, ModBlocks.blockStates.air, 0);
// Expand the re-render volume to include this block
renderBounds.union(absPos);
}
}
} else {
// Other types of legitimate breaking can set blocks to air directly which improves performance.
for (BlockPos absPos : Iterables.concat(destroyData.getPositions(PosType.BRANCHES), destroyData.getPositions(PosType.LEAVES))) {
// The client needs to set it's blocks to air
world.setBlockState(absPos, ModBlocks.blockStates.air, 0);
// Expand the re-render volume to include this block
renderBounds.union(absPos);
}
}
cleanupShellBlocks(destroyData);
// This forces the client to rerender the chunks
world.markBlockRangeForRenderUpdate(renderBounds.getMin(), renderBounds.getMax());
}
use of com.ferreusveritas.dynamictrees.util.BlockBounds in project DynamicTrees by DynamicTreesTeam.
the class BlockBranch method destroyLeaves.
/**
* Attempt to destroy all of the leaves on the branch while leaving the other leaves unharmed.
*
* @param world The world
* @param cutPos The position of the block that was initially destroyed
* @param species The species of the tree that is being modified
* @param endPoints The absolute positions of the branch endpoints
* @param destroyedLeaves A map for collecting the positions and blockstates for all of the leaves blocks that will
* be destroyed.
* @param drops A list for collecting the ItemStacks and their positions relative to the cut position
*/
protected void destroyLeaves(World world, BlockPos cutPos, Species species, List<BlockPos> endPoints, Map<BlockPos, IBlockState> destroyedLeaves, List<BlockItemStack> drops) {
if (!world.isRemote && !endPoints.isEmpty()) {
// Make a bounding volume that holds all of the endpoints and expand the volume by 3 blocks for the leaves radius
BlockBounds bounds = new BlockBounds(endPoints).expand(3);
// Create a voxmap to store the leaf destruction map
SimpleVoxmap vmap = new SimpleVoxmap(bounds);
// For each of the endpoints add a 7x7 destruction volume around it
for (BlockPos endPos : endPoints) {
for (BlockPos leafPos : BlockPos.getAllInBoxMutable(endPos.add(-3, -3, -3), endPos.add(3, 3, 3))) {
// Flag this position for destruction
vmap.setVoxel(leafPos, (byte) 1);
}
// We know that the endpoint does not have a leaves block in it because it was a branch
vmap.setVoxel(endPos, (byte) 0);
}
TreeFamily family = species.getFamily();
BlockBranch familyBranch = family.getDynamicBranch();
int primaryThickness = (int) family.getPrimaryThickness();
// Expand the volume yet again by 3 blocks in all directions and search for other non-destroyed endpoints
for (MutableBlockPos findPos : bounds.expand(3).iterate()) {
IBlockState findState = world.getBlockState(findPos);
if (familyBranch.getRadius(findState) == primaryThickness) {
// Search for endpoints of the same tree family
Iterable<MutableBlockPos> leaves = species.getLeavesProperties().getCellKit().getLeafCluster().getAllNonZero();
for (MutableBlockPos leafpos : leaves) {
vmap.setVoxel(findPos.getX() + leafpos.getX(), findPos.getY() + leafpos.getY(), findPos.getZ() + leafpos.getZ(), (byte) 0);
}
}
}
ArrayList<ItemStack> dropList = new ArrayList<ItemStack>();
// Destroy all family compatible leaves
for (Cell cell : vmap.getAllNonZeroCells()) {
MutableBlockPos pos = cell.getPos();
IBlockState state = world.getBlockState(pos);
if (species.isCompatibleLeaves(world, pos, state)) {
dropList.clear();
species.getTreeHarvestDrops(world, pos, dropList, world.rand);
// We are storing this so it must be immutable
BlockPos imPos = pos.toImmutable();
BlockPos relPos = imPos.subtract(cutPos);
// Covertly destroy the leaves on the server side
world.setBlockState(imPos, ModBlocks.blockStates.air, 0);
destroyedLeaves.put(relPos, state);
dropList.forEach(i -> drops.add(new BlockItemStack(i, relPos)));
}
}
}
}
Aggregations