Search in sources :

Example 1 with NodeFindEnds

use of com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds in project DynamicTrees by DynamicTreesTeam.

the class Species method getEnds.

/**
 * A little internal convenience function for getting branch endpoints
 *
 * @param world    The world
 * @param treePos  The {@link BlockPos} of the base of the {@link TreeFamily} trunk
 * @param treeBase The tree part that is the base of the {@link TreeFamily} trunk.  Provided for easy analysis.
 * @return A list of all branch endpoints for the {@link TreeFamily}
 */
protected final List<BlockPos> getEnds(World world, BlockPos treePos, ITreePart treeBase) {
    NodeFindEnds endFinder = new NodeFindEnds();
    treeBase.analyse(world.getBlockState(treePos), world, treePos, null, new MapSignal(endFinder));
    return endFinder.getEnds();
}
Also used : NodeFindEnds(com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds) MapSignal(com.ferreusveritas.dynamictrees.api.network.MapSignal)

Example 2 with NodeFindEnds

use of com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds in project DynamicTrees by DynamicTreesTeam.

the class FeatureGenFruit method postGrow.

@Override
public boolean postGrow(World world, BlockPos rootPos, BlockPos treePos, Species species, int soilLife, boolean natural) {
    IBlockState blockState = world.getBlockState(treePos);
    BlockBranch branch = TreeHelper.getBranch(blockState);
    if (branch != null && branch.getRadius(blockState) >= fruitingRadius && natural) {
        if (species.seasonalFruitProductionFactor(world, rootPos) > world.rand.nextFloat()) {
            NodeFindEnds endFinder = new NodeFindEnds();
            TreeHelper.startAnalysisFromRoot(world, rootPos, new MapSignal(endFinder));
            List<BlockPos> endPoints = endFinder.getEnds();
            int qty = getQuantity(false);
            if (!endPoints.isEmpty()) {
                for (int i = 0; i < qty; i++) {
                    BlockPos endPoint = endPoints.get(world.rand.nextInt(endPoints.size()));
                    addFruit(world, species, rootPos.up(), endPoint, false, true, SafeChunkBounds.ANY);
                }
            }
        }
    }
    return true;
}
Also used : NodeFindEnds(com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds) IBlockState(net.minecraft.block.state.IBlockState) BlockPos(net.minecraft.util.math.BlockPos) BlockBranch(com.ferreusveritas.dynamictrees.blocks.BlockBranch) MapSignal(com.ferreusveritas.dynamictrees.api.network.MapSignal)

Example 3 with NodeFindEnds

use of com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds in project DynamicTrees by DynamicTreesTeam.

the class FeatureGenPodzol method postGrow.

@Override
public boolean postGrow(World world, BlockPos rootPos, BlockPos treePos, Species species, int soilLife, boolean natural) {
    if (ModConfigs.podzolGen) {
        NodeFindEnds endFinder = new NodeFindEnds();
        TreeHelper.startAnalysisFromRoot(world, rootPos, new MapSignal(endFinder));
        List<BlockPos> endPoints = endFinder.getEnds();
        if (!endPoints.isEmpty()) {
            Random random = world.rand;
            BlockPos pos = endPoints.get(random.nextInt(endPoints.size()));
            int x = pos.getX() + random.nextInt(5) - 2;
            int z = pos.getZ() + random.nextInt(5) - 2;
            final int darkThreshold = 4;
            for (int i = 0; i < 32; i++) {
                BlockPos offPos = new BlockPos(x, pos.getY() - 1 - i, z);
                if (!world.isAirBlock(offPos)) {
                    Block block = world.getBlockState(offPos).getBlock();
                    if (block instanceof BlockBranch || block instanceof BlockMushroom || block instanceof BlockLeaves) {
                        // Skip past Mushrooms and branches on the way down
                        continue;
                    } else if (block instanceof BlockFlower || block instanceof BlockTallGrass || block instanceof BlockDoublePlant) {
                        // Kill Plants
                        if (world.getLightFor(EnumSkyBlock.SKY, offPos) <= darkThreshold) {
                            world.setBlockToAir(pos);
                        }
                        continue;
                    } else if (block == Blocks.DIRT || block == Blocks.GRASS) {
                        // Convert grass or dirt to podzol
                        if (world.getLightFor(EnumSkyBlock.SKY, offPos.up()) <= darkThreshold) {
                            world.setBlockState(offPos, ModBlocks.blockStates.podzol);
                        } else {
                            spreadPodzol(world, pos);
                        }
                    }
                    break;
                }
            }
        }
    }
    return true;
}
Also used : NodeFindEnds(com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds) BlockBranch(com.ferreusveritas.dynamictrees.blocks.BlockBranch) Random(java.util.Random) EnumSkyBlock(net.minecraft.world.EnumSkyBlock) BlockPos(net.minecraft.util.math.BlockPos) MapSignal(com.ferreusveritas.dynamictrees.api.network.MapSignal)

Example 4 with NodeFindEnds

use of com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds 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)

Aggregations

MapSignal (com.ferreusveritas.dynamictrees.api.network.MapSignal)4 NodeFindEnds (com.ferreusveritas.dynamictrees.systems.nodemappers.NodeFindEnds)4 BlockBranch (com.ferreusveritas.dynamictrees.blocks.BlockBranch)3 BlockPos (net.minecraft.util.math.BlockPos)3 IBlockState (net.minecraft.block.state.IBlockState)2 INodeInspector (com.ferreusveritas.dynamictrees.api.network.INodeInspector)1 ILeavesProperties (com.ferreusveritas.dynamictrees.api.treedata.ILeavesProperties)1 SpeciesPostGenerationEvent (com.ferreusveritas.dynamictrees.event.SpeciesPostGenerationEvent)1 SimpleVoxmap (com.ferreusveritas.dynamictrees.util.SimpleVoxmap)1 Cell (com.ferreusveritas.dynamictrees.util.SimpleVoxmap.Cell)1 Random (java.util.Random)1 Block (net.minecraft.block.Block)1 MutableBlockPos (net.minecraft.util.math.BlockPos.MutableBlockPos)1 EnumSkyBlock (net.minecraft.world.EnumSkyBlock)1