Search in sources :

Example 6 with ITreePart

use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.

the class CommandGrowPulse method execute.

@Override
public void execute(World world, ICommandSender sender, String[] args) throws CommandException {
    if (args.length < 4) {
        throw new WrongUsageException("commands.dynamictrees.growpulse.usage");
    }
    BlockPos pos = CommandBase.parseBlockPos(sender, args, 1, false);
    ITreePart part = TreeHelper.getTreePart(world.getBlockState(pos));
    if (part.isRootNode()) {
        TreeHelper.growPulse(world, pos);
    } else {
        throw new CommandException("commands.dynamictrees.growpulse.norootyerror", pos.getX() + " " + pos.getY() + " " + pos.getZ());
    }
}
Also used : ITreePart(com.ferreusveritas.dynamictrees.api.treedata.ITreePart) WrongUsageException(net.minecraft.command.WrongUsageException) BlockPos(net.minecraft.util.math.BlockPos) CommandException(net.minecraft.command.CommandException)

Example 7 with ITreePart

use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart 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 8 with ITreePart

use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.

the class BlockBranchBasic method analyse.

/**
 * This is a recursive algorithm used to explore the branch network.  It calls a run() function for the signal on
 * the way out and a returnRun() on the way back.
 * <p>
 * Okay so a little explanation here.. I've been hit up by people who claim that recursion is a bad idea.  The
 * reason why they think this is because java has to push values on the stack for each level of recursion and then
 * pop them off as the levels complete.  Many times this can lead to performance issues. Fine, I understand that.
 * The reason why it doesn't matter here is because of the object oriented nature of how the tree parts function
 * demand that a different analyze function be called for each object type.  Even if this were rewritten to be
 * iterative the same number of stack pushes and pops would need to be performed to run the custom function for each
 * node in the network anyway.  The depth of recursion for this algorithm is less than 32.  So there's no real risk
 * of a stack overflow.
 * <p>
 * The difference being that in an iterative design I would need to maintain a stack array holding all of the values
 * and push and pop them manually or use a stack index.  This is messy and not something I would want to maintain
 * for practically non-existent gains. Java does a pretty good job of managing the stack on its own.
 */
@Override
public MapSignal analyse(IBlockState blockState, World world, BlockPos pos, EnumFacing fromDir, MapSignal signal) {
    if (signal.overflow || (signal.trackVisited && signal.doTrackingVisited(pos))) {
        return signal;
    }
    if (signal.depth++ < getMaxSignalDepth()) {
        // Prevents going too deep into large networks, or worse, being caught in a network loop
        // Run the inspectors of choice
        signal.run(blockState, world, pos, fromDir);
        for (EnumFacing dir : EnumFacing.VALUES) {
            // Spread signal in various directions
            if (dir != fromDir) {
                // don't count where the signal originated from
                BlockPos deltaPos = pos.offset(dir);
                IBlockState deltaState = world.getBlockState(deltaPos);
                ITreePart treePart = TreeHelper.getTreePart(deltaState);
                if (treePart.shouldAnalyse()) {
                    signal = treePart.analyse(deltaState, world, deltaPos, dir.getOpposite(), signal);
                    // This should only be true for the originating block when the root node is found
                    if (signal.found && signal.localRootDir == null && fromDir == null) {
                        signal.localRootDir = dir;
                    }
                }
            }
        }
        signal.returnRun(blockState, world, pos, fromDir);
    } else {
        IBlockState state = world.getBlockState(pos);
        if (signal.destroyLoopedNodes && state.getBlock() instanceof BlockBranch) {
            BlockBranch branch = (BlockBranch) state.getBlock();
            // Destroy one of the offending nodes
            branch.breakDeliberate(world, pos, EnumDestroyMode.OVERFLOW);
        }
        signal.overflow = true;
    }
    signal.depth--;
    return signal;
}
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)

Example 9 with ITreePart

use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.

the class BlockBranchCactus method growSignal.

@Override
public GrowSignal growSignal(World world, BlockPos pos, GrowSignal signal) {
    if (signal.step()) {
        // This is always placed at the beginning of every growSignal function
        Species species = signal.getSpecies();
        // EnumFacing originDir = signal.dir.getOpposite(); // Direction this signal originated from
        // This must be cached on the stack for proper recursion
        EnumFacing targetDir = species.selectNewDirection(world, pos, this, signal);
        signal.doTurn(targetDir);
        BlockPos deltaPos = pos.offset(targetDir);
        IBlockState deltaState = world.getBlockState(deltaPos);
        // Pass grow signal to next block in path
        ITreePart treepart = TreeHelper.getTreePart(deltaState);
        if (treepart == this) {
            // Recurse
            signal = treepart.growSignal(world, deltaPos, signal);
        } else if (world.isAirBlock(deltaPos)) {
            signal = growIntoAir(world, deltaPos, signal, (int) signal.radius);
        }
    }
    return signal;
}
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) Species(com.ferreusveritas.dynamictrees.trees.Species)

Example 10 with ITreePart

use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.

the class BlockRooty method updateTree.

/**
 * @param world
 * @param rootPos
 * @param random
 * @param natural
 */
public void updateTree(IBlockState rootyState, World world, BlockPos rootPos, Random random, boolean natural) {
    if (CoordUtils.isSurroundedByLoadedChunks(world, rootPos)) {
        boolean viable = false;
        Species species = getSpecies(rootyState, world, rootPos);
        if (species.isValid()) {
            BlockPos treePos = rootPos.offset(getTrunkDirection(world, rootPos));
            ITreePart treeBase = TreeHelper.getTreePart(world.getBlockState(treePos));
            if (treeBase != TreeHelper.nullTreePart) {
                viable = species.update(world, this, rootPos, getSoilLife(rootyState, world, rootPos), treeBase, treePos, random, natural);
            }
        }
        if (!viable) {
            // TODO: Attempt to destroy what's left of the tree before setting rooty to dirt
            world.setBlockState(rootPos, getDecayBlockState(world, rootPos), 3);
        }
    }
}
Also used : ITreePart(com.ferreusveritas.dynamictrees.api.treedata.ITreePart) BlockPos(net.minecraft.util.math.BlockPos) Species(com.ferreusveritas.dynamictrees.trees.Species) TileEntitySpecies(com.ferreusveritas.dynamictrees.tileentity.TileEntitySpecies)

Aggregations

ITreePart (com.ferreusveritas.dynamictrees.api.treedata.ITreePart)11 IBlockState (net.minecraft.block.state.IBlockState)8 BlockPos (net.minecraft.util.math.BlockPos)7 EnumFacing (net.minecraft.util.EnumFacing)5 Species (com.ferreusveritas.dynamictrees.trees.Species)3 ICell (com.ferreusveritas.dynamictrees.api.cells.ICell)1 MapSignal (com.ferreusveritas.dynamictrees.api.network.MapSignal)1 ILeavesProperties (com.ferreusveritas.dynamictrees.api.treedata.ILeavesProperties)1 BlockBranch (com.ferreusveritas.dynamictrees.blocks.BlockBranch)1 TileEntitySpecies (com.ferreusveritas.dynamictrees.tileentity.TileEntitySpecies)1 SimpleVoxmap (com.ferreusveritas.dynamictrees.util.SimpleVoxmap)1 Random (java.util.Random)1 CommandException (net.minecraft.command.CommandException)1 WrongUsageException (net.minecraft.command.WrongUsageException)1