package buildcraft.core.lib.utils; import java.util.List; import net.minecraft.block.Block; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.world.BlockEvent; import buildcraft.BuildCraftCore; import buildcraft.core.proxy.CoreProxy; public class BlockMiner { protected final World world; protected final TileEntity owner; protected final int x, y, z, minerId; private boolean hasMined, hasFailed; private int energyRequired, energyAccepted; public BlockMiner(World world, TileEntity owner, int x, int y, int z) { this.world = world; this.owner = owner; this.x = x; this.y = y; this.z = z; this.minerId = world.rand.nextInt(); } public boolean hasMined() { return hasMined; } public boolean hasFailed() { return hasFailed; } public void mineStack(ItemStack stack) { // First, try to add to a nearby chest stack.stackSize -= Utils.addToRandomInventoryAround(owner.getWorldObj(), owner.xCoord, owner.yCoord, owner.zCoord, stack); // Second, try to add to adjacent pipes if (stack.stackSize > 0) { stack.stackSize -= Utils.addToRandomInjectableAround(owner.getWorldObj(), owner.xCoord, owner.yCoord, owner.zCoord, ForgeDirection.UNKNOWN, stack); } // Lastly, throw the object away if (stack.stackSize > 0) { float f = world.rand.nextFloat() * 0.8F + 0.1F; float f1 = world.rand.nextFloat() * 0.8F + 0.1F; float f2 = world.rand.nextFloat() * 0.8F + 0.1F; EntityItem entityitem = new EntityItem(owner.getWorldObj(), owner.xCoord + f, owner.yCoord + f1 + 0.5F, owner.zCoord + f2, stack); entityitem.lifespan = BuildCraftCore.itemLifespan * 20; entityitem.delayBeforeCanPickup = 10; float f3 = 0.05F; entityitem.motionX = (float) world.rand.nextGaussian() * f3; entityitem.motionY = (float) world.rand.nextGaussian() * f3 + 1.0F; entityitem.motionZ = (float) world.rand.nextGaussian() * f3; owner.getWorldObj().spawnEntityInWorld(entityitem); } } public void invalidate() { world.destroyBlockInWorldPartially(minerId, x, y, z, -1); } public int acceptEnergy(int offeredAmount) { if (BlockUtils.isUnbreakableBlock(world, x, y, z)) { hasFailed = true; return 0; } energyRequired = BlockUtils.computeBlockBreakEnergy(world, x, y, z); int usedAmount = MathUtils.clamp(offeredAmount, 0, Math.max(0, energyRequired - energyAccepted)); energyAccepted += usedAmount; if (energyAccepted >= energyRequired) { world.destroyBlockInWorldPartially(minerId, x, y, z, -1); hasMined = true; Block block = world.getBlock(x, y, z); int meta = world.getBlockMetadata(x, y, z); BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(x, y, z, world, block, meta, CoreProxy.proxy.getBuildCraftPlayer((WorldServer) owner.getWorldObj(), owner.xCoord, owner.yCoord, owner.zCoord).get()); MinecraftForge.EVENT_BUS.post(breakEvent); if (!breakEvent.isCanceled()) { List<ItemStack> stacks = BlockUtils.getItemStackFromBlock((WorldServer) world, x, y, z); if (stacks != null) { for (ItemStack s : stacks) { if (s != null) { mineStack(s); } } } world.playAuxSFXAtEntity( null, 2001, x, y, z, Block.getIdFromBlock(block) + (meta << 12)); world.setBlockToAir(x, y, z); } else { hasFailed = true; } } else { world.destroyBlockInWorldPartially(minerId, x, y, z, MathUtils.clamp((int) Math.floor(energyAccepted * 10 / energyRequired), 0, 9)); } return usedAmount; } }