use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.
the class BlockBranchBasic 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
IBlockState currBlockState = world.getBlockState(pos);
Species species = signal.getSpecies();
boolean inTrunk = signal.isInTrunk();
// Direction this signal originated from
EnumFacing originDir = signal.dir.getOpposite();
// 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 != TreeHelper.nullTreePart) {
// Recurse
signal = treepart.growSignal(world, deltaPos, signal);
} else if (world.isAirBlock(deltaPos) || deltaState.getBlock() == ModBlocks.blockTrunkShell) {
signal = growIntoAir(world, deltaPos, signal, getRadius(currBlockState));
}
}
// Calculate Branch Thickness based on neighboring branches
// Start by accumulating the branch we just came from
float areaAccum = signal.radius * signal.radius;
for (EnumFacing dir : EnumFacing.VALUES) {
if (!dir.equals(originDir) && !dir.equals(targetDir)) {
// Don't count where the signal originated from or the branch we just came back from
BlockPos deltaPos = pos.offset(dir);
// If it is decided to implement a special block(like a squirrel hole, tree
// swing, rotting, burned or infested branch, etc) then this new block could be
// derived from BlockBranch and this works perfectly. Should even work with
// tileEntity blocks derived from BlockBranch.
IBlockState blockState = world.getBlockState(deltaPos);
ITreePart treepart = TreeHelper.getTreePart(blockState);
if (isSameTree(treepart)) {
int branchRadius = treepart.getRadius(blockState);
areaAccum += branchRadius * branchRadius;
}
}
}
// Only continue to set radii if the tree growth isn't choked out
if (!signal.choked) {
// Ensure that side branches are not thicker than the size of a block. Also enforce species max thickness
int maxRadius = inTrunk ? species.maxBranchRadius() : Math.min(species.maxBranchRadius(), RADMAX_NORMAL);
// The new branch should be the square root of all of the sums of the areas of the branches coming into it.
// But it shouldn't be smaller than it's current size(prevents the instant slimming effect when chopping off branches)
// WOW!
signal.radius = MathHelper.clamp((float) Math.sqrt(areaAccum) + species.getTapering(), getRadius(currBlockState), maxRadius);
int targetRadius = (int) Math.floor(signal.radius);
int setRad = setRadius(world, pos, targetRadius, originDir);
if (setRad < targetRadius) {
// We tried to set a radius but it didn't comply because something is in the way.
// If something is in the way then it means that the tree growth is choked
signal.choked = true;
}
}
}
return signal;
}
use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.
the class BlockDynamicLeaves method needLeaves.
/**
* Will place a leaves block if the position is air and it's possible to create one there. Otherwise it will check
* to see if the block is already there.
*
* @param world
* @param leavesProperties
* @return True if the leaves are now at the coordinates.
*/
public boolean needLeaves(World world, BlockPos pos, ILeavesProperties leavesProperties) {
if (world.isAirBlock(pos)) {
// Place Leaves if Air
return this.growLeavesIfLocationIsSuitable(world, leavesProperties, pos, leavesProperties.getCellKit().getDefaultHydration());
} else {
// Otherwise check if there's already this type of leaves there.
IBlockState blockState = world.getBlockState(pos);
ITreePart treepart = TreeHelper.getTreePart(blockState);
// Check if this is the same type of leaves
return treepart == this && leavesProperties == getProperties(blockState);
}
}
use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.
the class BlockDynamicLeaves method getHydrationLevelFromNeighbors.
/**
* Gathers hydration levels from neighbors before pushing the values into the solver
*/
public int getHydrationLevelFromNeighbors(IBlockAccess access, BlockPos pos, ILeavesProperties leavesProp) {
ICell[] cells = new ICell[6];
for (EnumFacing dir : EnumFacing.VALUES) {
BlockPos deltaPos = pos.offset(dir);
IBlockState state = access.getBlockState(deltaPos);
ITreePart part = TreeHelper.getTreePart(state);
cells[dir.ordinal()] = part.getHydrationCell(access, deltaPos, state, dir, leavesProp);
}
// Find center cell's value from neighbors
return leavesProp.getCellKit().getCellSolver().solve(cells);
}
use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.
the class BlockDynamicLeaves method isBottom.
/**
* Used to find if the leaf block is at the bottom of the stack
*/
public static boolean isBottom(World world, BlockPos pos) {
IBlockState belowBlockState = world.getBlockState(pos.down());
ITreePart belowTreepart = TreeHelper.getTreePart(belowBlockState);
if (belowTreepart != TreeHelper.nullTreePart) {
// False for leaves, twigs, and dirt. True for stocky branches
return belowTreepart.getRadius(belowBlockState) > 1;
}
// Non-Tree parts below indicate the bottom of stack
return true;
}
use of com.ferreusveritas.dynamictrees.api.treedata.ITreePart in project DynamicTrees by DynamicTreesTeam.
the class ClientProxy method crushLeavesBlock.
@Override
public void crushLeavesBlock(World world, BlockPos pos, IBlockState blockState, Entity entity) {
if (world.isRemote) {
Random random = world.rand;
ITreePart treePart = TreeHelper.getTreePart(blockState);
if (treePart instanceof BlockDynamicLeaves) {
BlockDynamicLeaves leaves = (BlockDynamicLeaves) treePart;
ILeavesProperties leavesProperties = leaves.getProperties(blockState);
int color = getFoliageColor(leavesProperties, world, blockState, pos);
float r = (color >> 16 & 255) / 255.0F;
float g = (color >> 8 & 255) / 255.0F;
float b = (color & 255) / 255.0F;
for (int dz = 0; dz < 8; dz++) {
for (int dy = 0; dy < 8; dy++) {
for (int dx = 0; dx < 8; dx++) {
if (random.nextInt(8) == 0) {
double fx = pos.getX() + dx / 8.0;
double fy = pos.getY() + dy / 8.0;
double fz = pos.getZ() + dz / 8.0;
addDustParticle(world, fx, fy, fz, 0, random.nextFloat() * entity.motionY, 0, blockState, r, g, b);
}
}
}
}
}
}
}
Aggregations