Search in sources :

Example 1 with BlockBounds

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;
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) Block(net.minecraft.block.Block) BlockHugeMushroom(net.minecraft.block.BlockHugeMushroom) BlockPos(net.minecraft.util.math.BlockPos) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) SimpleVoxmap(com.ferreusveritas.dynamictrees.util.SimpleVoxmap) BlockBounds(com.ferreusveritas.dynamictrees.util.BlockBounds) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) Cell(com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell)

Example 2 with BlockBounds

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());
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) BlockPos(net.minecraft.util.math.BlockPos) BlockBounds(com.ferreusveritas.dynamictrees.util.BlockBounds)

Example 3 with BlockBounds

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)));
            }
        }
    }
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) SimpleVoxmap(com.ferreusveritas.dynamictrees.util.SimpleVoxmap) TreeFamily(com.ferreusveritas.dynamictrees.trees.TreeFamily) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) BlockPos(net.minecraft.util.math.BlockPos) ItemStack(net.minecraft.item.ItemStack) BlockBounds(com.ferreusveritas.dynamictrees.util.BlockBounds) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) Cell(com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell)

Aggregations

BlockBounds (com.ferreusveritas.dynamictrees.util.BlockBounds)3 IBlockState (net.minecraft.block.state.IBlockState)3 BlockPos (net.minecraft.util.math.BlockPos)3 SimpleVoxmap (com.ferreusveritas.dynamictrees.util.SimpleVoxmap)2 Cell (com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell)2 MutableBlockPos (net.minecraft.util.math.BlockPos.MutableBlockPos)2 TreeFamily (com.ferreusveritas.dynamictrees.trees.TreeFamily)1 Block (net.minecraft.block.Block)1 BlockHugeMushroom (net.minecraft.block.BlockHugeMushroom)1 ItemStack (net.minecraft.item.ItemStack)1 NBTTagCompound (net.minecraft.nbt.NBTTagCompound)1