Search in sources :

Example 16 with BlockBranch

use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.

the class NodeInflator method returnRun.

@Override
public boolean returnRun(IBlockState blockState, World world, BlockPos pos, EnumFacing fromDir) {
    // Calculate Branch Thickness based on neighboring branches
    BlockBranch branch = TreeHelper.getBranch(blockState);
    if (branch != null) {
        // Start by accumulating the branch we just came from
        float areaAccum = radius * radius;
        boolean isTwig = true;
        for (EnumFacing dir : EnumFacing.VALUES) {
            if (!dir.equals(fromDir)) {
                // Don't count where the signal originated from
                BlockPos dPos = pos.offset(dir);
                if (dPos.equals(last)) {
                    // or the branch we just came back from
                    // on the return journey if the block we just came from is a branch we are obviously not the endpoint(twig)
                    isTwig = false;
                    continue;
                }
                IBlockState deltaBlockState = world.getBlockState(dPos);
                ITreePart treepart = TreeHelper.getTreePart(deltaBlockState);
                if (branch.isSameTree(treepart)) {
                    int branchRadius = treepart.getRadius(deltaBlockState);
                    areaAccum += branchRadius * branchRadius;
                }
            }
        }
        if (isTwig) {
            // Handle leaves here
            if (leafMap != null) {
                // 16(bit 5) is code for a twig
                leafMap.setVoxel(pos, (byte) 16);
                SimpleVoxmap leafCluster = species.getLeavesProperties().getCellKit().getLeafCluster();
                leafMap.blitMax(pos, leafCluster);
            }
        } else {
            // The new branch should be the square root of all of the sums of the areas of the branches coming into it.
            radius = (float) Math.sqrt(areaAccum) + (species.getTapering() * species.getWorldGenTaperingFactor());
            // Ensure the branch is never inflated past it's species maximum
            int maxRadius = species.maxBranchRadius();
            if (radius > maxRadius) {
                radius = maxRadius;
            }
            // Ensure non-twig branches are at least radius 2
            float secondaryThickness = species.getFamily().getSecondaryThickness();
            if (radius < secondaryThickness) {
                radius = secondaryThickness;
            }
            branch.setRadius(world, pos, (int) Math.floor(radius), null);
            if (leafMap != null) {
                // 32(bit 6) is code for a branch
                leafMap.setVoxel(pos, (byte) 32);
            }
        }
        last = pos;
    }
    return false;
}
Also used : ITreePart(com.ferreusveritas.dynamictrees.api.treedata.ITreePart) IBlockState(net.minecraft.block.state.IBlockState) EnumFacing(net.minecraft.util.EnumFacing) BlockPos(net.minecraft.util.math.BlockPos) SimpleVoxmap(com.ferreusveritas.dynamictrees.util.SimpleVoxmap) BlockBranch(com.ferreusveritas.dynamictrees.blocks.BlockBranch)

Example 17 with BlockBranch

use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.

the class JoCode method generate.

/**
 * Generate a tree from a JoCode instruction list.
 *
 * @param world   The world
 * @param seed    The seed used to create the tree
 * @param rootPos The position of what will become the rootydirt block
 * @param biome   The biome of the coordinates.
 * @param facing  Direction of tree
 * @param radius  Constraint radius
 */
public void generate(World world, Species species, BlockPos rootPosIn, Biome biome, EnumFacing facing, int radius, SafeChunkBounds safeBounds) {
    boolean worldGen = safeBounds != SafeChunkBounds.ANY;
    // A Tree generation boundary radius is at least 2 and at most 8
    radius = MathHelper.clamp(radius, 2, 8);
    setFacing(facing);
    BlockPos rootPos = species.preGeneration(world, rootPosIn, radius, facing, safeBounds, this);
    if (rootPos != BlockPos.ORIGIN) {
        // Save the initial state of the dirt in case this fails
        IBlockState initialDirtState = world.getBlockState(rootPos);
        // Set to unfertilized rooty dirt
        species.placeRootyDirtBlock(world, rootPos, 0);
        // Make the tree branch structure
        generateFork(world, species, 0, rootPos, false);
        // Establish a position for the bottom block of the trunk
        BlockPos treePos = rootPos.up();
        // Fix branch thicknesses and map out leaf locations
        IBlockState treeState = world.getBlockState(treePos);
        BlockBranch branch = TreeHelper.getBranch(treeState);
        if (branch != null) {
            // If a branch exists then the growth was successful
            ILeavesProperties leavesProperties = species.getLeavesProperties();
            SimpleVoxmap leafMap = new SimpleVoxmap(radius * 2 + 1, species.getWorldGenLeafMapHeight(), radius * 2 + 1).setMapAndCenter(treePos, new BlockPos(radius, 0, radius));
            // This is responsible for thickening the branches
            INodeInspector inflator = species.getNodeInflator(leafMap);
            // This is responsible for gathering a list of branch end points
            NodeFindEnds endFinder = new NodeFindEnds();
            // The inflator signal will "paint" a temporary voxmap of all of the leaves and branches.
            MapSignal signal = new MapSignal(inflator, endFinder);
            // During worldgen we will not destroy looped nodes
            signal.destroyLoopedNodes = careful;
            branch.analyse(treeState, world, treePos, EnumFacing.DOWN, signal);
            if (signal.found || signal.overflow) {
                // Something went terribly wrong.
                DynamicTrees.log.debug("Non-viable branch network detected during world generation @ " + treePos);
                DynamicTrees.log.debug("Species: " + species);
                DynamicTrees.log.debug("Radius: " + radius);
                DynamicTrees.log.debug("JoCode: " + this);
                // Completely blow away any improperly defined network nodes
                cleanupFrankentree(world, treePos, treeState, endFinder.getEnds(), safeBounds);
                // Now that everything is clear we may as well regenerate the tree that screwed everything up.
                if (!secondChanceRegen) {
                    secondChanceRegen = true;
                    generate(world, species, rootPosIn, biome, facing, radius, safeBounds);
                }
                secondChanceRegen = false;
                return;
            }
            List<BlockPos> endPoints = endFinder.getEnds();
            // Use the voxmap to precompute leaf smothering so we don't have to age it as many times.
            smother(leafMap, leavesProperties);
            // Place Growing Leaves Blocks from voxmap
            for (Cell cell : leafMap.getAllNonZeroCells((byte) 0x0F)) {
                // Iterate through all of the cells that are leaves(not air or branches)
                MutableBlockPos cellPos = cell.getPos();
                if (safeBounds.inBounds(cellPos, false)) {
                    IBlockState testBlockState = world.getBlockState(cellPos);
                    Block testBlock = testBlockState.getBlock();
                    if (testBlock.isReplaceable(world, cellPos)) {
                        // Flag 16 to prevent observers from causing cascading lag
                        world.setBlockState(cellPos, leavesProperties.getDynamicLeavesState(cell.getValue()), worldGen ? 16 : 2);
                    }
                } else {
                    leafMap.setVoxel(cellPos, (byte) 0);
                }
            }
            // Shrink the leafMap down by the safeBounds object so that the aging process won't look for neighbors outside of the bounds.
            for (Cell cell : leafMap.getAllNonZeroCells()) {
                MutableBlockPos cellPos = cell.getPos();
                if (!safeBounds.inBounds(cellPos, true)) {
                    leafMap.setVoxel(cellPos, (byte) 0);
                }
            }
            // Age volume for 3 cycles using a leafmap
            TreeHelper.ageVolume(world, leafMap, species.getWorldGenAgeIterations(), safeBounds);
            // Rot the unsupported branches
            if (species.handleRot(world, endPoints, rootPos, treePos, 0, safeBounds)) {
                // The entire tree rotted away before it had a chance
                return;
            }
            // Allow for special decorations by the tree itself
            species.postGeneration(world, rootPos, biome, radius, endPoints, safeBounds, initialDirtState);
            MinecraftForge.EVENT_BUS.post(new SpeciesPostGenerationEvent(world, species, rootPos, endPoints, safeBounds, initialDirtState));
            // Add snow to parts of the tree in chunks where snow was already placed
            addSnow(leafMap, world, rootPos, biome);
        } else {
            // The growth failed.. turn the soil back to what it was
            world.setBlockState(rootPos, initialDirtState, careful ? 3 : 2);
        }
    }
}
Also used : INodeInspector(com.ferreusveritas.dynamictrees.api.network.INodeInspector) NodeFindEnds(com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds) IBlockState(net.minecraft.block.state.IBlockState) SpeciesPostGenerationEvent(com.ferreusveritas.dynamictrees.event.SpeciesPostGenerationEvent) SimpleVoxmap(com.ferreusveritas.dynamictrees.util.SimpleVoxmap) BlockBranch(com.ferreusveritas.dynamictrees.blocks.BlockBranch) ILeavesProperties(com.ferreusveritas.dynamictrees.api.treedata.ILeavesProperties) Block(net.minecraft.block.Block) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) BlockPos(net.minecraft.util.math.BlockPos) Cell(com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell) MutableBlockPos(net.minecraft.util.math.BlockPos.MutableBlockPos) MapSignal(com.ferreusveritas.dynamictrees.api.network.MapSignal)

Example 18 with BlockBranch

use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.

the class ModelHelper method regModel.

/**
 * Registers models associated with the tree. At the moment this only deals with {@link BlockBranch} blocks
 *
 * @param tree
 */
public static void regModel(TreeFamily tree) {
    BlockBranch blockBranch = tree.getDynamicBranch();
    ModelResourceLocation modelLocation = getBranchModelResourceLocation(blockBranch);
    setGenericStateMapper(blockBranch, modelLocation);
    if (blockBranch instanceof BlockBranchThick) {
        setGenericStateMapper(((BlockBranchThick) blockBranch).otherBlock, modelLocation);
    }
    BlockSurfaceRoot surfaceRoot = tree.getSurfaceRoots();
    if (surfaceRoot != null) {
        ModelLoader.setCustomStateMapper(surfaceRoot, new StateMap.Builder().ignore(surfaceRoot.getIgnorableProperties()).build());
    }
}
Also used : BlockBranchThick(com.ferreusveritas.dynamictrees.blocks.BlockBranchThick) StateMap(net.minecraft.client.renderer.block.statemap.StateMap) ModelResourceLocation(net.minecraft.client.renderer.block.model.ModelResourceLocation) BlockBranch(com.ferreusveritas.dynamictrees.blocks.BlockBranch) BlockSurfaceRoot(com.ferreusveritas.dynamictrees.blocks.BlockSurfaceRoot)

Aggregations

BlockBranch (com.ferreusveritas.dynamictrees.blocks.BlockBranch)18 IBlockState (net.minecraft.block.state.IBlockState)14 BlockPos (net.minecraft.util.math.BlockPos)12 MapSignal (com.ferreusveritas.dynamictrees.api.network.MapSignal)6 EnumFacing (net.minecraft.util.EnumFacing)6 Block (net.minecraft.block.Block)5 MutableBlockPos (net.minecraft.util.math.BlockPos.MutableBlockPos)4 NodeFindEnds (com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds)3 SimpleVoxmap (com.ferreusveritas.dynamictrees.util.SimpleVoxmap)3 IExtendedBlockState (net.minecraftforge.common.property.IExtendedBlockState)3 ILeavesProperties (com.ferreusveritas.dynamictrees.api.treedata.ILeavesProperties)2 NodeCollector (com.ferreusveritas.dynamictrees.systems.nodemappers.NodeCollector)2 Species (com.ferreusveritas.dynamictrees.trees.Species)2 Cell (com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell)2 IBakedModel (net.minecraft.client.renderer.block.model.IBakedModel)2 ItemStack (net.minecraft.item.ItemStack)2 NutRecipe (com.eerussianguy.firmalife.recipe.NutRecipe)1 INodeInspector (com.ferreusveritas.dynamictrees.api.network.INodeInspector)1 ITreePart (com.ferreusveritas.dynamictrees.api.treedata.ITreePart)1 BlockBranchThick (com.ferreusveritas.dynamictrees.blocks.BlockBranchThick)1