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).
This commit is contained in:
abel1502 2025-06-02 14:32:00 +03:00
parent 4a931a4be1
commit 5d7fc996e5
No known key found for this signature in database
GPG Key ID: 076926596A536338

View File

@ -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<ItemStack> 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) {