From 5d7fc996e591a313d22d16991bea01d7ce23d80e Mon Sep 17 00:00:00 2001 From: abel1502 Date: Mon, 2 Jun 2025 14:32:00 +0300 Subject: [PATCH] Make autosaw replant crops It doesn't seem too far-fetched to suggest the seeds that fall to the ground are replanted in a natural way. I had to replace the old ray-tracing approach with a more straightforward iteration over all possibly affected blocks (under 400, most of them skipped). In terms of performance this seems on par with the original solution (the raytrace function alone did 200 iterations). --- .../machine/TileEntityMachineAutosaw.java | 106 ++++++++++++++---- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAutosaw.java b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAutosaw.java index af5d11cf7..d7bddd3a1 100644 --- a/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAutosaw.java +++ b/src/main/java/com/hbm/tileentity/machine/TileEntityMachineAutosaw.java @@ -1,5 +1,6 @@ package com.hbm.tileentity.machine; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -22,14 +23,20 @@ import cpw.mods.fml.relauncher.SideOnly; import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.block.BlockLeaves; +import net.minecraft.block.IGrowable; import net.minecraft.block.material.Material; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityItem; import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; +import net.minecraft.world.World; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.ForgeDirection; public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IBufPacketReceiver, IFluidStandardReceiver, IFluidCopiable { @@ -119,29 +126,40 @@ public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IB this.rotationYaw -= 360; } - Vec3 grace = Vec3.createVectorHelper(0, 0, -3.5); - grace.rotateAroundY(-(float) Math.toRadians(rotationYaw)); - grace.xCoord += pivot.xCoord; - grace.yCoord += pivot.yCoord; - grace.zCoord += pivot.zCoord; + final double CUT_ANGLE = Math.toRadians(5); + double rotationYawRads = Math.toRadians((rotationYaw + 270) % 360); - Vec3 detector = Vec3.createVectorHelper(0, 0, -9); - detector.rotateAroundY(-(float) Math.toRadians(rotationYaw)); - detector.xCoord += pivot.xCoord; - detector.yCoord += pivot.yCoord; - detector.zCoord += pivot.zCoord; - MovingObjectPosition pos = worldObj.func_147447_a(grace, detector, false, false, false); + outer: + for(int dx = -9; dx <= 9; dx++) { + for(int dz = -9; dz <= 9; dz++) { + int sqrDst = dx * dx + dz * dz; - if(pos != null && pos.typeOfHit == pos.typeOfHit.BLOCK) { + if(sqrDst <= 4 || sqrDst > 81) + continue; + + double angle = Math.atan2(dz, dx); + double relAngle = Math.abs(angle - rotationYawRads); + relAngle = Math.abs((relAngle + Math.PI) % (2 * Math.PI) - Math.PI); - Block b = worldObj.getBlock(pos.blockX, pos.blockY, pos.blockZ); + if(relAngle > CUT_ANGLE) + continue; - if(b.getMaterial() == Material.wood || b.getMaterial() == Material.leaves || b.getMaterial() == Material.plants) { + int x = xCoord + dx; + int y = yCoord + 1; + int z = zCoord + dz; - int meta = worldObj.getBlockMetadata(pos.blockX, pos.blockY, pos.blockZ); - if(!shouldIgnore(b, meta)) { - state = 1; - } + Block b = worldObj.getBlock(x, y, z); + if(!(b.getMaterial() == Material.wood || b.getMaterial() == Material.leaves || b.getMaterial() == Material.plants)) + continue; + + int meta = worldObj.getBlockMetadata(x, y, z); + if(shouldIgnore(worldObj, x, y, z, b, meta)) + continue; + + // com.hbm.main.MainRegistry.logger.info("[Abel] found target at " + x + ", " + y + ", " + z + ", angle=" + rotationYaw); + + state = 1; + break outer; } } } @@ -212,11 +230,15 @@ public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IB } /** Anything additionally that the detector nor the blades should pick up on, like non-mature willows */ - public static boolean shouldIgnore(Block b, int meta) { + public static boolean shouldIgnore(World world, int x, int y, int z, Block b, int meta) { if(b == ModBlocks.plant_tall) { return meta == EnumTallFlower.CD2.ordinal() + 8 || meta == EnumTallFlower.CD3.ordinal() + 8; } + if((b instanceof IGrowable)) { + return ((IGrowable) b).func_149851_a(world, x, y, z, world.isRemote); + } + return false; } @@ -225,12 +247,12 @@ public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IB Block b = worldObj.getBlock(x, y, z); int meta = worldObj.getBlockMetadata(x, y, z); - if(shouldIgnore(b, meta)) { + if(shouldIgnore(worldObj, x, y, z, b, meta)) { return; } if(b.getMaterial() == Material.leaves || b.getMaterial() == Material.plants) { - worldObj.func_147480_a(x, y, z, true); + cutCrop(x, y, z); return; } @@ -242,6 +264,48 @@ public class TileEntityMachineAutosaw extends TileEntityLoadedBase implements IB } } + protected void cutCrop(int x, int y, int z) { + + Block soil = worldObj.getBlock(x, y - 1, z); + + Block b = worldObj.getBlock(x, y, z); + int meta = worldObj.getBlockMetadata(x, y, z); + + worldObj.playAuxSFX(2001, x, y, z, Block.getIdFromBlock(b) + (meta << 12)); + + Block replacementBlock = Blocks.air; + int replacementMeta = 0; + + if (!worldObj.isRemote && !worldObj.restoringBlockSnapshots) { + ArrayList drops = b.getDrops(worldObj, x, y, z, meta, 0); + boolean replanted = false; + + for (ItemStack drop : drops) { + if (!replanted && drop.getItem() instanceof IPlantable) { + IPlantable seed = (IPlantable) drop.getItem(); + + if(soil.canSustainPlant(worldObj, x, y - 1, z, ForgeDirection.UP, seed)) { + replacementBlock = seed.getPlant(worldObj, x, y, z); + replacementMeta = seed.getPlantMetadata(worldObj, x, y, z); + replanted = true; + drop.stackSize -= 1; + } + } + + float delta = 0.7F; + double dx = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D; + double dy = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D; + double dz = (double)(worldObj.rand.nextFloat() * delta) + (double)(1.0F - delta) * 0.5D; + + EntityItem entityItem = new EntityItem(worldObj, x + dx, y + dy, z + dz, drop); + entityItem.delayBeforeCanPickup = 10; + worldObj.spawnEntityInWorld(entityItem); + } + } + + worldObj.setBlock(x, y, z, replacementBlock, replacementMeta, 3); + } + protected void fellTree(int x, int y, int z) { if(worldObj.getBlock(x, y - 1, z).getMaterial() == Material.wood) {