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());
}
}
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;
}
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;
}
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;
}
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);
}
}
}
Aggregations