use of com.ferreusveritas.dynamictrees.util.BranchDestructionData in project DynamicTrees by DynamicTreesTeam.
the class BlockBranch method onBlockExploded.
// /////////////////////////////////////////
// EXPLOSIONS AND FIRE
// /////////////////////////////////////////
// Explosive harvesting methods will likely result in mostly sticks but I'm okay with that since it kinda makes sense.
@Override
public void onBlockExploded(World world, BlockPos pos, Explosion explosion) {
IBlockState state = world.getBlockState(pos);
if (state.getBlock() == this) {
Species species = TreeHelper.getExactSpecies(world, pos);
BranchDestructionData destroyData = destroyBranchFromNode(world, pos, EnumFacing.DOWN, false);
float woodVolume = destroyData.woodVolume;
List<ItemStack> woodDropList = getLogDrops(world, pos, species, woodVolume);
EntityFallingTree treeEntity = EntityFallingTree.dropTree(world, destroyData, woodDropList, DestroyType.BLAST);
if (treeEntity != null) {
Vec3d expPos = explosion.getPosition();
EntityLivingBase placer = explosion.getExplosivePlacedBy();
// Since the size of an explosion is private we have to make some assumptions.. TNT: 4, Creeper: 3, Creeper+: 6
float size = (placer instanceof EntityCreeper) ? (((EntityCreeper) placer).getPowered() ? 6 : 3) : 4;
double distance = treeEntity.getDistance(expPos.x, expPos.y, expPos.z);
if (distance / size <= 1.0D && distance != 0.0D) {
treeEntity.motionX += (treeEntity.posX - expPos.x) / distance;
treeEntity.motionY += (treeEntity.posY - expPos.y) / distance;
treeEntity.motionZ += (treeEntity.posZ - expPos.z) / distance;
}
}
}
}
use of com.ferreusveritas.dynamictrees.util.BranchDestructionData in project DynamicTrees by DynamicTreesTeam.
the class BlockBranch method futureBreak.
/*
1.10.2 Simplified Block Harvesting Logic Flow(for no silk touch)
tryHarvestBlock {
canHarvest = canHarvestBlock() <- (ForgeHooks.canHarvestBlock occurs in here)
removed = removeBlock(canHarvest) {
removedByPlayer() {
onBlockHarvested()
world.setBlockState() <- block is set to air here
}
}
if (removed) harvestBlock() {
fortune = getEnchantmentLevel(FORTUNE)
dropBlockAsItem(fortune) {
dropBlockAsItemWithChance(fortune) {
items = getDrops(fortune) {
getItemDropped(fortune) {
Item.getItemFromBlock(this) <- (Standard block behavior)
}
}
ForgeEventFactory.fireBlockHarvesting(items) <- (BlockEvent.HarvestDropsEvent)
(for all items) -> spawnAsEntity(item)
}
}
}
}
*/
@Override
public void futureBreak(IBlockState state, World world, BlockPos cutPos, EntityLivingBase entity) {
// Try to get the face being pounded on
final double reachDistance = entity instanceof EntityPlayerMP ? entity.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue() : 5.0D;
RayTraceResult rtResult = playerRayTrace(entity, reachDistance, 1.0F);
EnumFacing toolDir = rtResult != null ? (entity.isSneaking() ? rtResult.sideHit.getOpposite() : rtResult.sideHit) : EnumFacing.DOWN;
if (toolDir == null) {
// Some rayTracing results can theoretically produce a face hit with no side designation.
// Make everything better
toolDir = EnumFacing.DOWN;
}
// Do the actual destruction
BranchDestructionData destroyData = destroyBranchFromNode(world, cutPos, toolDir, false);
// Get all of the wood drops
ItemStack heldItem = entity.getHeldItemMainhand();
int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, heldItem);
float fortuneFactor = 1.0f + 0.25f * fortune;
// The amount of wood calculated from the body of the tree network
float woodVolume = destroyData.woodVolume;
List<ItemStack> woodItems = getLogDrops(world, cutPos, destroyData.species, woodVolume * fortuneFactor);
if (entity.getActiveHand() == null) {
// What the hell man? I trusted you!
// Players do things with hands.
entity.setActiveHand(EnumHand.MAIN_HAND);
}
float chance = 1.0f;
// Fire the block harvesting event. For An-Sar's PrimalCore mod :)
if (entity instanceof EntityPlayer) {
chance = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(woodItems, world, cutPos, state, fortune, chance, false, (EntityPlayer) entity);
}
final float finalChance = chance;
// Build the final wood drop list taking chance into consideration
List<ItemStack> woodDropList = woodItems.stream().filter(i -> world.rand.nextFloat() <= finalChance).collect(Collectors.toList());
// This will drop the EntityFallingTree into the world
EntityFallingTree.dropTree(world, destroyData, woodDropList, DestroyType.HARVEST);
// Damage the axe by a prescribed amount
damageAxe(entity, heldItem, getRadius(state), woodVolume);
}
use of com.ferreusveritas.dynamictrees.util.BranchDestructionData in project DynamicTrees by DynamicTreesTeam.
the class BlockBranch method destroyBranchFromNode.
/**
* Destroys all branches recursively not facing the branching direction with the root node
*
* @param world The world
* @param cutPos The position of the branch being lobbed
* @param toolDir The face that was pounded on when breaking the block at cutPos
* @param wholeTree Indicates if the whole tree should be destroyed or just the branch
* @return The volume of the portion of the tree that was destroyed
*/
public BranchDestructionData destroyBranchFromNode(World world, BlockPos cutPos, EnumFacing toolDir, boolean wholeTree) {
IBlockState blockState = world.getBlockState(cutPos);
NodeSpecies nodeSpecies = new NodeSpecies();
// Analyze entire tree network to find root node and species
MapSignal signal = analyse(blockState, world, cutPos, null, new MapSignal(nodeSpecies));
// Get the species from the root node
Species species = nodeSpecies.getSpecies();
// Analyze only part of the tree beyond the break point and map out the extended block states
// We can't destroy the branches during this step since we need accurate extended block states that include connections
NodeExtState extStateMapper = new NodeExtState(cutPos);
analyse(blockState, world, cutPos, wholeTree ? null : signal.localRootDir, new MapSignal(extStateMapper));
// Analyze only part of the tree beyond the break point and calculate it's volume, then destroy the branches
NodeNetVolume volumeSum = new NodeNetVolume();
NodeDestroyer destroyer = new NodeDestroyer(species);
destroyMode = EnumDestroyMode.HARVEST;
analyse(blockState, world, cutPos, wholeTree ? null : signal.localRootDir, new MapSignal(volumeSum, destroyer));
destroyMode = EnumDestroyMode.SLOPPY;
// Destroy all the leaves on the branch, store them in a map and convert endpoint coordinates from absolute to relative
List<BlockPos> endPoints = destroyer.getEnds();
Map<BlockPos, IBlockState> destroyedLeaves = new HashMap<>();
List<BlockItemStack> leavesDropsList = new ArrayList<>();
destroyLeaves(world, cutPos, species, endPoints, destroyedLeaves, leavesDropsList);
endPoints = endPoints.stream().map(p -> p.subtract(cutPos)).collect(Collectors.toList());
// Calculate main trunk height
int trunkHeight = 1;
for (BlockPos iter = new BlockPos(0, 1, 0); extStateMapper.getExtStateMap().containsKey(iter); iter = iter.up()) {
trunkHeight++;
}
EnumFacing cutDir = signal.localRootDir;
if (cutDir == null) {
cutDir = EnumFacing.DOWN;
}
return new BranchDestructionData(species, extStateMapper.getExtStateMap(), destroyedLeaves, leavesDropsList, endPoints, volumeSum.getVolume(), cutPos, cutDir, toolDir, trunkHeight);
}
Aggregations