use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.
the class ModelEntityFallingTree method generateTreeQuads.
public List<TreeQuadData> generateTreeQuads(EntityFallingTree entity, World world) {
final BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
final BranchDestructionData destructionData = entity.getDestroyData();
final Species species = destructionData.species;
final BlockPos cutPos = destructionData.cutPos;
final EnumFacing cutDir = destructionData.cutDir;
final ArrayList<TreeQuadData> treeQuads = new ArrayList<>();
if (destructionData.getNumBranches() <= 0) {
return treeQuads;
}
// Draw the ring texture cap on the cut block
IExtendedBlockState exState = destructionData.getBranchBlockState(0);
if (exState == null) {
return treeQuads;
}
for (EnumFacing face : EnumFacing.VALUES) {
exState = exState.withProperty(BlockBranch.CONNECTIONS[face.getIndex()], face == cutDir.getOpposite() ? 8 : 0);
}
int radius = ((BlockBranch) exState.getBlock()).getRadius(exState);
float offset = (8 - Math.min(radius, BlockBranch.RADMAX_NORMAL)) / 16f;
// Since we source the blockState from the destruction data it will always be the same
IBakedModel branchModel = dispatcher.getModelForState(exState.getClean());
treeQuads.addAll(toTreeQuadData(QuadManipulator.getQuads(branchModel, exState, new Vec3d(BlockPos.ORIGIN.offset(cutDir)).scale(offset), new EnumFacing[] { cutDir }), 0xFFFFFFFF, exState.getClean()));
// Draw the rest of the tree/branch
for (int index = 0; index < destructionData.getNumBranches(); index++) {
Block previousBranch = exState.getBlock();
exState = destructionData.getBranchBlockState(index);
if (// Update the branch model only if the block is different
!previousBranch.equals(exState.getBlock())) {
branchModel = dispatcher.getModelForState(exState.getClean());
}
BlockPos relPos = destructionData.getBranchRelPos(index);
treeQuads.addAll(toTreeQuadData(QuadManipulator.getQuads(branchModel, exState, new Vec3d(relPos)), 0xFFFFFFFF, exState.getClean()));
}
// Draw the leaves
HashMap<BlockPos, IBlockState> leavesClusters = species.getFamily().getFellingLeavesClusters(destructionData);
if (leavesClusters != null) {
for (Entry<BlockPos, IBlockState> leafLoc : leavesClusters.entrySet()) {
IBlockState leafState = leafLoc.getValue();
if (leafState instanceof IExtendedBlockState) {
leafState = ((IExtendedBlockState) leafState).getClean();
}
treeQuads.addAll(toTreeQuadData(QuadManipulator.getQuads(dispatcher.getModelForState(leafState), leafLoc.getValue(), new Vec3d(leafLoc.getKey())), species.getLeavesProperties().foliageColorMultiplier(leafState, world, cutPos), leafState));
}
} else {
for (int index = 0; index < destructionData.getNumLeaves(); index++) {
BlockPos relPos = destructionData.getLeavesRelPos(index);
IBlockState state = destructionData.getLeavesBlockState(index);
IBakedModel leavesModel = dispatcher.getModelForState(state);
treeQuads.addAll(toTreeQuadData(QuadManipulator.getQuads(leavesModel, state, new Vec3d(relPos)), destructionData.getLeavesProperties(index).foliageColorMultiplier(state, world, cutPos.add(relPos)), state));
}
}
return treeQuads;
}
use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.
the class JoCode method cleanupFrankentree.
/**
* Attempt to clean up fused trees that have multiple root blocks by simply destroying them both messily
*/
protected void cleanupFrankentree(World world, BlockPos treePos, IBlockState treeState, List<BlockPos> endPoints, SafeChunkBounds safeBounds) {
Set<BlockPos> blocksToDestroy = new HashSet<>();
BlockBranch branch = TreeHelper.getBranch(treeState);
MapSignal signal = new MapSignal(new NodeCollector(blocksToDestroy));
signal.destroyLoopedNodes = false;
signal.trackVisited = true;
branch.analyse(treeState, world, treePos, null, signal);
BlockBranch.destroyMode = EnumDestroyMode.IGNORE;
for (BlockPos pos : blocksToDestroy) {
if (safeBounds.inBounds(pos, false)) {
IBlockState branchState = world.getBlockState(pos);
Optional<BlockBranch> branchBlock = TreeHelper.getBranchOpt(branchState);
if (branchBlock.isPresent()) {
int radius = branchBlock.get().getRadius(branchState);
TreeFamily family = branchBlock.get().getFamily();
Species species = family.getCommonSpecies();
if (family.getPrimaryThickness() == radius) {
ILeavesProperties leavesProperties = species.getLeavesProperties();
if (leavesProperties != LeavesProperties.NULLPROPERTIES) {
SimpleVoxmap leafCluster = leavesProperties.getCellKit().getLeafCluster();
if (leafCluster != LeafClusters.NULLMAP) {
for (Cell cell : leafCluster.getAllNonZeroCells()) {
BlockPos delPos = pos.add(cell.getPos());
if (safeBounds.inBounds(delPos, false)) {
IBlockState leavesState = world.getBlockState(delPos);
if (TreeHelper.isLeaves(leavesState)) {
BlockDynamicLeaves leavesBlock = (BlockDynamicLeaves) leavesState.getBlock();
if (leavesProperties.getTree() == leavesBlock.getProperties(leavesState).getTree()) {
world.setBlockState(delPos, ModBlocks.blockStates.air, 2);
}
}
}
}
}
}
}
world.setBlockState(pos, ModBlocks.blockStates.air, 2);
}
}
}
BlockBranch.destroyMode = EnumDestroyMode.HARVEST;
// Now wreck out all surrounding leaves. Let them grow back naturally.
/*if(!endPoints.isEmpty()) {
BlockBounds bounds = new BlockBounds(endPoints);
bounds.expand(3);
for(BlockPos pos : bounds.iterate()) {
if(safeBounds.inBounds(pos, false)) {
if(TreeHelper.isLeaves(world.getBlockState(pos))) {
world.setBlockState(pos, ModBlocks.blockStates.air, 2);
}
}
}
}*/
}
use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.
the class TreeJungle method onTreeActivated.
@Override
public boolean onTreeActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) {
// Place Cocoa Pod if we are holding Cocoa Beans
if (heldItem != null) {
if (heldItem.getItem() == Items.DYE && heldItem.getItemDamage() == 3) {
BlockBranch branch = TreeHelper.getBranch(state);
if (branch != null && branch.getRadius(state) == 8) {
if (side != EnumFacing.UP && side != EnumFacing.DOWN) {
pos = pos.offset(side);
}
if (world.isAirBlock(pos)) {
IBlockState cocoaState = ModBlocks.blockFruitCocoa.getStateForPlacement(world, pos, side, hitX, hitY, hitZ, 0, player);
EnumFacing facing = cocoaState.getValue(BlockHorizontal.FACING);
world.setBlockState(pos, ModBlocks.blockFruitCocoa.getDefaultState().withProperty(BlockHorizontal.FACING, facing), 2);
if (!player.capabilities.isCreativeMode) {
heldItem.shrink(1);
}
return true;
}
}
}
}
// Need this here to apply potions or bone meal.
return super.onTreeActivated(world, pos, state, player, hand, heldItem, side, hitX, hitY, hitZ);
}
use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.
the class ChunkTreeHelper method removeAllBranchesFromChunk.
/**
* Removes all trees that have branches in a chunk area.
* to prevent partial trees in adjacent chunks. Useful
* for removing trees prior to pruning world chunks.
*
* @param world The world
* @param cPos The chunk position where the effect is intended
* @param radius Radius of effect in chunk width units
*/
public static void removeAllBranchesFromChunk(World world, ChunkPos cPos, int radius) {
if (cPos == null) {
// Who would be so unkind?
throw new NullPointerException("Null Chunk Position");
}
BlockBounds bounds = getEffectiveBlockBounds(world, cPos, radius);
for (MutableBlockPos pos : bounds.iterate()) {
IBlockState state = world.getBlockState(pos);
Optional<BlockBranch> branchBlock = TreeHelper.getBranchOpt(state);
if (branchBlock.isPresent()) {
doTreeDestroy(world, branchBlock, pos);
}
}
}
use of com.ferreusveritas.dynamictrees.blocks.BlockBranch in project DynamicTrees by DynamicTreesTeam.
the class ChunkTreeHelper method removeOrphanedBranchNodes.
/**
* Removes floating little bits of tree that have somehow lost
* connection with their parent root system.
*
* @param world The world
* @param cPos The chunk position where the effect is intended
* @param radius Radius of effect in chunk width units
*/
public static void removeOrphanedBranchNodes(World world, ChunkPos cPos, int radius) {
if (cPos == null) {
// Who would be so unkind?
throw new NullPointerException("Null Chunk Position");
}
// This is used to track branches that are already proven
Set<BlockPos> found = new HashSet<>();
BlockBounds bounds = getEffectiveBlockBounds(world, cPos, radius);
for (MutableBlockPos pos : bounds.iterate()) {
if (found.contains(pos)) {
// Block was already proven to be part of a valid tree structure
continue;
}
// Test if there's a branch block at this position
IBlockState state = world.getBlockState(pos);
Optional<BlockBranch> branchBlock = TreeHelper.getBranchOpt(state);
if (!branchBlock.isPresent()) {
// No branch block found at this position. Move on
continue;
}
// Test if the branch has a root node attached to it
BlockPos rootPos = TreeHelper.findRootNode(world, pos);
if (rootPos == BlockPos.ORIGIN) {
// If the root position is the ORIGIN object it means that no root block was found
// If the root node isn't found then all nodes are orphan. Destroy the entire network.
doTreeDestroy(world, branchBlock, rootPos);
continue;
}
// There is at least one root block in the network
IBlockState rootyState = world.getBlockState(rootPos);
Optional<BlockRooty> rootyBlock = TreeHelper.getRootyOpt(rootyState);
if (!rootyBlock.isPresent()) {
// This theoretically shouldn't ever happen
continue;
}
// Rooty block confirmed, build details about the trunk coming out of it
EnumFacing trunkDir = rootyBlock.get().getTrunkDirection(world, rootPos);
BlockPos trunkPos = rootPos.offset(trunkDir);
IBlockState trunkState = world.getBlockState(trunkPos);
Optional<BlockBranch> trunk = TreeHelper.getBranchOpt(trunkState);
if (!trunk.isPresent()) {
// This theoretically shouldn't ever happen
continue;
}
// There's a trunk coming out of the rooty block, that's kinda expected. But is it the only rooty block in the network?
MapSignal signal = new MapSignal();
signal.destroyLoopedNodes = false;
trunk.get().analyse(trunkState, world, trunkPos, null, signal);
if (signal.multiroot || signal.overflow) {
// We found multiple root nodes. This can't be resolved. Destroy the entire network
doTreeDestroy(world, branchBlock, pos);
continue;
} else {
// Tree appears healthy with only a single attached root block
trunk.get().analyse(trunkState, world, trunkPos, null, new MapSignal(new NodeCollector(found)));
}
}
}
Aggregations