diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/BlockCrafting.java b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/BlockCrafting.java index 2d3f85f4f..9f4f45a06 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/BlockCrafting.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/BlockCrafting.java @@ -681,7 +681,7 @@ public final class BlockCrafting{ RecipeHandler.addOreDictRecipe(new ItemStack(InitBlocks.blockGreenhouseGlass, 3), "GSG", "SDS", "GSG", 'G', "blockGlass", - 'D', new ItemStack(InitBlocks.blockCrystalEmpowered, 1, TheCrystals.LAPIS.ordinal()), + 'D', new ItemStack(InitBlocks.blockCrystal, 1, TheCrystals.LAPIS.ordinal()), 'S', "treeSapling"); recipeGlass = RecipeUtil.lastIRecipe(); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemDrill.java b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemDrill.java index b792cc7b0..04595b780 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemDrill.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/items/ItemDrill.java @@ -10,7 +10,12 @@ package de.ellpeck.actuallyadditions.mod.items; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + import com.google.common.collect.Multimap; + import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; import de.ellpeck.actuallyadditions.mod.blocks.metalists.TheColoredLampColors; import de.ellpeck.actuallyadditions.mod.config.values.ConfigStringListValues; @@ -18,7 +23,11 @@ import de.ellpeck.actuallyadditions.mod.inventory.ContainerDrill; import de.ellpeck.actuallyadditions.mod.inventory.GuiHandler; import de.ellpeck.actuallyadditions.mod.items.base.ItemEnergy; import de.ellpeck.actuallyadditions.mod.tile.TileEntityInventoryBase; -import de.ellpeck.actuallyadditions.mod.util.*; +import de.ellpeck.actuallyadditions.mod.util.ItemStackHandlerCustom; +import de.ellpeck.actuallyadditions.mod.util.ItemUtil; +import de.ellpeck.actuallyadditions.mod.util.ModUtil; +import de.ellpeck.actuallyadditions.mod.util.StackUtil; +import de.ellpeck.actuallyadditions.mod.util.WorldUtil; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -34,18 +43,19 @@ import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumRarity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.*; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.EnumFacing.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; -import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - public class ItemDrill extends ItemEnergy{ public static final int HARVEST_LEVEL = 4; @@ -55,13 +65,6 @@ public class ItemDrill extends ItemEnergy{ super(250000, 1000, name); this.setMaxDamage(0); this.setHasSubtypes(true); - - //For Iguana Tweaks author - // - //You know what? It's bad, when you know - //There is already getHarvestLevel(), yo - //But then Iguana comes and fucks with you - //So that you need to use setHarvestLevel() too. this.setHarvestLevel("shovel", HARVEST_LEVEL); this.setHarvestLevel("pickaxe", HARVEST_LEVEL); } @@ -221,19 +224,18 @@ public class ItemDrill extends ItemEnergy{ //Block hit RayTraceResult ray = WorldUtil.getNearestBlockWithDefaultReachDistance(player.world, player); if(ray != null){ - int side = ray.sideHit.ordinal(); - + //Breaks the Blocks if(!player.isSneaking() && this.getHasUpgrade(stack, ItemDrillUpgrade.UpgradeType.THREE_BY_THREE)){ if(this.getHasUpgrade(stack, ItemDrillUpgrade.UpgradeType.FIVE_BY_FIVE)){ - toReturn = this.breakBlocks(stack, 2, player.world, side != 0 && side != 1 ? pos.up() : pos, side, player); + toReturn = this.breakBlocks(stack, 2, player.world, pos, ray.sideHit, player); } else{ - toReturn = this.breakBlocks(stack, 1, player.world, pos, side, player); + toReturn = this.breakBlocks(stack, 1, player.world, pos, ray.sideHit, player); } } else{ - toReturn = this.breakBlocks(stack, 0, player.world, pos, side, player); + toReturn = this.breakBlocks(stack, 0, player.world, pos, ray.sideHit, player); } //Removes Enchantments added above @@ -385,17 +387,17 @@ public class ItemDrill extends ItemEnergy{ * @param world The World * @param player The Player who breaks the Blocks */ - public boolean breakBlocks(ItemStack stack, int radius, World world, BlockPos aPos, int side, EntityPlayer player){ + public boolean breakBlocks(ItemStack stack, int radius, World world, BlockPos aPos, EnumFacing side, EntityPlayer player){ int xRange = radius; int yRange = radius; int zRange = 0; //Corrects Blocks to hit depending on Side of original Block hit - if(side == 0 || side == 1){ + if(side.getAxis() == Axis.Y){ zRange = radius; yRange = 0; } - if(side == 4 || side == 5){ + if(side.getAxis() == Axis.X){ xRange = 0; zRange = radius; } @@ -414,6 +416,14 @@ public class ItemDrill extends ItemEnergy{ else{ return false; } + + if(radius == 2 && side.getAxis() != Axis.Y) { + aPos = aPos.up(); + IBlockState theState = world.getBlockState(aPos); + if(theState.getBlockHardness(world, aPos) <= mainHardness+5.0F){ + this.tryHarvestBlock(world, aPos, true, stack, player, use); + } + } //Break Blocks around if(radius > 0 && mainHardness >= 0.2F){ @@ -455,13 +465,13 @@ public class ItemDrill extends ItemEnergy{ IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); float hardness = state.getBlockHardness(world, pos); - boolean canHarvest = (ForgeHooks.canHarvestBlock(block, player, world, pos) || this.canHarvestBlock(state, stack)) && (!isExtra || this.getDestroySpeed(stack, world.getBlockState(pos)) > 1.0F); + boolean canHarvest = WorldUtil.canBreakExtraBlock(stack, world, player, pos); if(hardness >= 0.0F && (!isExtra || (canHarvest && !block.hasTileEntity(world.getBlockState(pos))))){ if(!player.capabilities.isCreativeMode){ this.extractEnergyInternal(stack, use, false); } //Break the Block - return WorldUtil.playerHarvestBlock(stack, world, player, pos); + return WorldUtil.breakExtraBlock(stack, world, player, pos); } return false; } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java index 194ed4491..8c902db85 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/ClientProxy.java @@ -11,33 +11,54 @@ package de.ellpeck.actuallyadditions.mod.proxy; +import java.util.ArrayList; +import java.util.List; + import de.ellpeck.actuallyadditions.mod.ClientRegistryHandler; -import de.ellpeck.actuallyadditions.mod.blocks.render.*; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderBatteryBox; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderCompost; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderDisplayStand; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderEmpowerer; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderLaserRelay; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderReconstructorLens; +import de.ellpeck.actuallyadditions.mod.blocks.render.RenderSmileyCloud; import de.ellpeck.actuallyadditions.mod.entity.InitEntities; import de.ellpeck.actuallyadditions.mod.entity.RenderWorm; import de.ellpeck.actuallyadditions.mod.event.ClientEvents; import de.ellpeck.actuallyadditions.mod.misc.special.SpecialRenderInit; -import de.ellpeck.actuallyadditions.mod.tile.*; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityAtomicReconstructor; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityBatteryBox; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityCompost; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityDisplayStand; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityEmpowerer; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelay; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayEnergy; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayEnergyAdvanced; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayEnergyExtreme; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayFluids; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayItem; +import de.ellpeck.actuallyadditions.mod.tile.TileEntityLaserRelayItemWhitelist; +import de.ellpeck.actuallyadditions.mod.tile.TileEntitySmileyCloud; import de.ellpeck.actuallyadditions.mod.util.IColorProvidingBlock; import de.ellpeck.actuallyadditions.mod.util.IColorProvidingItem; import de.ellpeck.actuallyadditions.mod.util.ModUtil; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.network.play.client.CPacketPlayerDigging; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import java.util.ArrayList; -import java.util.List; - public class ClientProxy implements IProxy{ private static final List COLOR_PRODIVIDING_ITEMS_FOR_REGISTERING = new ArrayList(); @@ -117,4 +138,12 @@ public class ClientProxy implements IProxy{ public EntityPlayer getCurrentPlayer(){ return Minecraft.getMinecraft().player; } + + @Override + public void sendBreakPacket(BlockPos pos) { + NetHandlerPlayClient netHandlerPlayClient = Minecraft.getMinecraft().getConnection(); + assert netHandlerPlayClient != null; + netHandlerPlayClient.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, pos, Minecraft + .getMinecraft().objectMouseOver.sideHit)); + } } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/IProxy.java b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/IProxy.java index 1aa2ec9e3..4c7ff7ed0 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/IProxy.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/proxy/IProxy.java @@ -15,6 +15,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -34,5 +35,7 @@ public interface IProxy{ void addColoredBlock(Block block); EntityPlayer getCurrentPlayer(); + + default void sendBreakPacket(BlockPos pos) {}; } diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java b/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java index 53530efa3..24f2434ea 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/util/WorldUtil.java @@ -16,24 +16,22 @@ import java.util.List; import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler; import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; -import de.ellpeck.actuallyadditions.mod.config.values.ConfigBoolValues; import de.ellpeck.actuallyadditions.mod.tile.FilterSettings; import de.ellpeck.actuallyadditions.mod.util.compat.SlotlessableItemHandlerWrapper; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.network.play.client.CPacketPlayerDigging; import net.minecraft.network.play.server.SPacketBlockChange; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; @@ -48,417 +46,419 @@ import net.minecraftforge.common.util.FakePlayerFactory; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.energy.IEnergyStorage; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.BlockEvent.BreakEvent; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.items.IItemHandler; -public final class WorldUtil{ +public final class WorldUtil { - public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract){ - return doItemInteraction(extractWrapper, insertWrapper, maxExtract, null); - } + public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract) { + return doItemInteraction(extractWrapper, insertWrapper, maxExtract, null); + } - public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract, FilterSettings filter){ - return doItemInteraction(extractWrapper, insertWrapper, maxExtract, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, filter); - } + public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract, FilterSettings filter) { + return doItemInteraction(extractWrapper, insertWrapper, maxExtract, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, filter); + } - public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract, int extractSlotStart, int extractSlotEnd, int insertSlotStart, int insertSlotEnd, FilterSettings filter){ - ItemStack theoreticalExtract = extractItem(extractWrapper, maxExtract, true, extractSlotStart, extractSlotEnd, filter); - if(StackUtil.isValid(theoreticalExtract)){ - ItemStack remaining = insertItem(insertWrapper, theoreticalExtract, false, insertSlotStart, insertSlotEnd); - if(!ItemStack.areItemStacksEqual(remaining, theoreticalExtract)){ - int toExtract = !StackUtil.isValid(remaining) ? StackUtil.getStackSize(theoreticalExtract) : StackUtil.getStackSize(theoreticalExtract)-StackUtil.getStackSize(remaining); - extractItem(extractWrapper, toExtract, false, extractSlotStart, extractSlotEnd, filter); - return true; - } - } - return false; - } + public static boolean doItemInteraction(SlotlessableItemHandlerWrapper extractWrapper, SlotlessableItemHandlerWrapper insertWrapper, int maxExtract, int extractSlotStart, int extractSlotEnd, int insertSlotStart, int insertSlotEnd, FilterSettings filter) { + ItemStack theoreticalExtract = extractItem(extractWrapper, maxExtract, true, extractSlotStart, extractSlotEnd, filter); + if (StackUtil.isValid(theoreticalExtract)) { + ItemStack remaining = insertItem(insertWrapper, theoreticalExtract, false, insertSlotStart, insertSlotEnd); + if (!ItemStack.areItemStacksEqual(remaining, theoreticalExtract)) { + int toExtract = !StackUtil.isValid(remaining) ? StackUtil.getStackSize(theoreticalExtract) : StackUtil.getStackSize(theoreticalExtract) - StackUtil.getStackSize(remaining); + extractItem(extractWrapper, toExtract, false, extractSlotStart, extractSlotEnd, filter); + return true; + } + } + return false; + } - public static ItemStack extractItem(SlotlessableItemHandlerWrapper extractWrapper, int maxExtract, boolean simulate, int slotStart, int slotEnd, FilterSettings filter){ - ItemStack extracted = StackUtil.getEmpty(); + public static ItemStack extractItem(SlotlessableItemHandlerWrapper extractWrapper, int maxExtract, boolean simulate, int slotStart, int slotEnd, FilterSettings filter) { + ItemStack extracted = StackUtil.getEmpty(); - if(ActuallyAdditions.commonCapsLoaded){ - Object handler = extractWrapper.getSlotlessHandler(); - if(handler instanceof ISlotlessItemHandler){ - ISlotlessItemHandler slotless = (ISlotlessItemHandler)handler; + if (ActuallyAdditions.commonCapsLoaded) { + Object handler = extractWrapper.getSlotlessHandler(); + if (handler instanceof ISlotlessItemHandler) { + ISlotlessItemHandler slotless = (ISlotlessItemHandler) handler; - if(filter == null || !filter.needsCheck()){ - extracted = slotless.extractItem(maxExtract, simulate); - return extracted; - } - else{ - ItemStack would = slotless.extractItem(maxExtract, true); - if(filter.check(would)){ - if(simulate){ - extracted = would; - } - else{ - extracted = slotless.extractItem(maxExtract, false); - } - } - //Leave the possibility to fall back to vanilla when there is a filter - } - } - } + if (filter == null || !filter.needsCheck()) { + extracted = slotless.extractItem(maxExtract, simulate); + return extracted; + } else { + ItemStack would = slotless.extractItem(maxExtract, true); + if (filter.check(would)) { + if (simulate) { + extracted = would; + } else { + extracted = slotless.extractItem(maxExtract, false); + } + } + //Leave the possibility to fall back to vanilla when there is a filter + } + } + } - if(!StackUtil.isValid(extracted)){ - IItemHandler handler = extractWrapper.getNormalHandler(); - if(handler != null){ - for(int i = Math.max(0, slotStart); i < Math.min(slotEnd, handler.getSlots()); i++){ - if(filter == null || !filter.needsCheck() || filter.check(handler.getStackInSlot(i))){ - extracted = handler.extractItem(i, maxExtract, simulate); + if (!StackUtil.isValid(extracted)) { + IItemHandler handler = extractWrapper.getNormalHandler(); + if (handler != null) { + for (int i = Math.max(0, slotStart); i < Math.min(slotEnd, handler.getSlots()); i++) { + if (filter == null || !filter.needsCheck() || filter.check(handler.getStackInSlot(i))) { + extracted = handler.extractItem(i, maxExtract, simulate); - if(StackUtil.isValid(extracted)){ - break; - } - } - } - } - } + if (StackUtil.isValid(extracted)) { + break; + } + } + } + } + } - return extracted; - } + return extracted; + } - public static ItemStack insertItem(SlotlessableItemHandlerWrapper insertWrapper, ItemStack stack, boolean simulate, int slotStart, int slotEnd){ - ItemStack remain = StackUtil.validateCopy(stack); + public static ItemStack insertItem(SlotlessableItemHandlerWrapper insertWrapper, ItemStack stack, boolean simulate, int slotStart, int slotEnd) { + ItemStack remain = StackUtil.validateCopy(stack); - if(ActuallyAdditions.commonCapsLoaded){ - Object handler = insertWrapper.getSlotlessHandler(); - if(handler instanceof ISlotlessItemHandler){ - remain = ((ISlotlessItemHandler)handler).insertItem(remain, simulate); + if (ActuallyAdditions.commonCapsLoaded) { + Object handler = insertWrapper.getSlotlessHandler(); + if (handler instanceof ISlotlessItemHandler) { + remain = ((ISlotlessItemHandler) handler).insertItem(remain, simulate); - if(!ItemStack.areItemStacksEqual(remain, stack)){ - return remain; - } - } - } + if (!ItemStack.areItemStacksEqual(remain, stack)) { return remain; } + } + } - IItemHandler handler = insertWrapper.getNormalHandler(); - if(handler != null){ - for(int i = Math.max(0, slotStart); i < Math.min(slotEnd, handler.getSlots()); i++){ - remain = handler.insertItem(i, remain, simulate); - } - } + IItemHandler handler = insertWrapper.getNormalHandler(); + if (handler != null) { + for (int i = Math.max(0, slotStart); i < Math.min(slotEnd, handler.getSlots()); i++) { + remain = handler.insertItem(i, remain, simulate); + } + } - return remain; - } + return remain; + } - public static void doEnergyInteraction(TileEntity tileFrom, TileEntity tileTo, EnumFacing sideTo, int maxTransfer){ - if(maxTransfer > 0){ - EnumFacing opp = sideTo == null ? null : sideTo.getOpposite(); - if(tileFrom.hasCapability(CapabilityEnergy.ENERGY, sideTo) && tileTo.hasCapability(CapabilityEnergy.ENERGY, opp)){ - IEnergyStorage handlerFrom = tileFrom.getCapability(CapabilityEnergy.ENERGY, sideTo); - IEnergyStorage handlerTo = tileTo.getCapability(CapabilityEnergy.ENERGY, opp); + public static void doEnergyInteraction(TileEntity tileFrom, TileEntity tileTo, EnumFacing sideTo, int maxTransfer) { + if (maxTransfer > 0) { + EnumFacing opp = sideTo == null ? null : sideTo.getOpposite(); + if (tileFrom.hasCapability(CapabilityEnergy.ENERGY, sideTo) && tileTo.hasCapability(CapabilityEnergy.ENERGY, opp)) { + IEnergyStorage handlerFrom = tileFrom.getCapability(CapabilityEnergy.ENERGY, sideTo); + IEnergyStorage handlerTo = tileTo.getCapability(CapabilityEnergy.ENERGY, opp); - if(handlerFrom != null && handlerTo != null){ - int drain = handlerFrom.extractEnergy(maxTransfer, true); - if(drain > 0){ - int filled = handlerTo.receiveEnergy(drain, false); - handlerFrom.extractEnergy(filled, false); - return; - } - } - } - } - } + if (handlerFrom != null && handlerTo != null) { + int drain = handlerFrom.extractEnergy(maxTransfer, true); + if (drain > 0) { + int filled = handlerTo.receiveEnergy(drain, false); + handlerFrom.extractEnergy(filled, false); + return; + } + } + } + } + } - public static void doFluidInteraction(TileEntity tileFrom, TileEntity tileTo, EnumFacing sideTo, int maxTransfer){ - if(maxTransfer > 0){ - if(tileFrom.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo) && tileTo.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo.getOpposite())){ - IFluidHandler handlerFrom = tileFrom.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo); - IFluidHandler handlerTo = tileTo.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo.getOpposite()); - FluidStack drain = handlerFrom.drain(maxTransfer, false); - if(drain != null){ - int filled = handlerTo.fill(drain.copy(), true); - handlerFrom.drain(filled, true); - } - } - } - } + public static void doFluidInteraction(TileEntity tileFrom, TileEntity tileTo, EnumFacing sideTo, int maxTransfer) { + if (maxTransfer > 0) { + if (tileFrom.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo) && tileTo.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo.getOpposite())) { + IFluidHandler handlerFrom = tileFrom.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo); + IFluidHandler handlerTo = tileTo.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, sideTo.getOpposite()); + FluidStack drain = handlerFrom.drain(maxTransfer, false); + if (drain != null) { + int filled = handlerTo.fill(drain.copy(), true); + handlerFrom.drain(filled, true); + } + } + } + } - /** - * Checks if a given Block with a given Meta is present in given Positions - * - * @param positions The Positions, an array of {x, y, z} arrays containing Positions - * @param block The Block - * @param meta The Meta - * @param world The World - * @return Is every block present? - */ - public static boolean hasBlocksInPlacesGiven(BlockPos[] positions, Block block, int meta, World world){ - for(BlockPos pos : positions){ - IBlockState state = world.getBlockState(pos); - if(!(state.getBlock() == block && block.getMetaFromState(state) == meta)){ - return false; - } - } - return true; - } + /** + * Checks if a given Block with a given Meta is present in given Positions + * + * @param positions The Positions, an array of {x, y, z} arrays containing Positions + * @param block The Block + * @param meta The Meta + * @param world The World + * @return Is every block present? + */ + public static boolean hasBlocksInPlacesGiven(BlockPos[] positions, Block block, int meta, World world) { + for (BlockPos pos : positions) { + IBlockState state = world.getBlockState(pos); + if (!(state.getBlock() == block && block.getMetaFromState(state) == meta)) { return false; } + } + return true; + } - public static ItemStack useItemAtSide(EnumFacing side, World world, BlockPos pos, ItemStack stack){ - if(world instanceof WorldServer && StackUtil.isValid(stack) && pos != null){ - BlockPos offsetPos = pos.offset(side); - IBlockState state = world.getBlockState(offsetPos); - Block block = state.getBlock(); - boolean replaceable = block.isReplaceable(world, offsetPos); + public static ItemStack useItemAtSide(EnumFacing side, World world, BlockPos pos, ItemStack stack) { + if (world instanceof WorldServer && StackUtil.isValid(stack) && pos != null) { + BlockPos offsetPos = pos.offset(side); + IBlockState state = world.getBlockState(offsetPos); + Block block = state.getBlock(); + boolean replaceable = block.isReplaceable(world, offsetPos); - //Redstone - if(replaceable && stack.getItem() == Items.REDSTONE){ - world.setBlockState(offsetPos, Blocks.REDSTONE_WIRE.getDefaultState(), 2); - return StackUtil.addStackSize(stack, -1); - } + //Redstone + if (replaceable && stack.getItem() == Items.REDSTONE) { + world.setBlockState(offsetPos, Blocks.REDSTONE_WIRE.getDefaultState(), 2); + return StackUtil.addStackSize(stack, -1); + } - //Plants - if(replaceable && stack.getItem() instanceof IPlantable){ - if(((IPlantable)stack.getItem()).getPlant(world, offsetPos).getBlock().canPlaceBlockAt(world, offsetPos)){ - if(world.setBlockState(offsetPos, ((IPlantable)stack.getItem()).getPlant(world, offsetPos), 2)){ - return StackUtil.addStackSize(stack, -1); - } - } - } + //Plants + if (replaceable && stack.getItem() instanceof IPlantable) { + if (((IPlantable) stack.getItem()).getPlant(world, offsetPos).getBlock().canPlaceBlockAt(world, offsetPos)) { + if (world.setBlockState(offsetPos, ((IPlantable) stack.getItem()).getPlant(world, offsetPos), 2)) { return StackUtil.addStackSize(stack, -1); } + } + } - //Everything else - try{ - if(world instanceof WorldServer){ - FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer)world); - ItemStack heldBefore = fake.getHeldItemMainhand(); - setHandItemWithoutAnnoyingSound(fake, EnumHand.MAIN_HAND, stack.copy()); + //Everything else + try { + if (world instanceof WorldServer) { + FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) world); + ItemStack heldBefore = fake.getHeldItemMainhand(); + setHandItemWithoutAnnoyingSound(fake, EnumHand.MAIN_HAND, stack.copy()); - fake.getHeldItemMainhand().onItemUse(fake, world, offsetPos, fake.getActiveHand(), side.getOpposite(), 0.5F, 0.5F, 0.5F); + fake.getHeldItemMainhand().onItemUse(fake, world, offsetPos, fake.getActiveHand(), side.getOpposite(), 0.5F, 0.5F, 0.5F); - ItemStack result = fake.getHeldItem(EnumHand.MAIN_HAND); - setHandItemWithoutAnnoyingSound(fake, EnumHand.MAIN_HAND, heldBefore); - return result; - } - } - catch(Exception e){ - ModUtil.LOGGER.error("Something that places Blocks at "+offsetPos.getX()+", "+offsetPos.getY()+", "+offsetPos.getZ()+" in World "+world.provider.getDimension()+" threw an Exception! Don't let that happen again!", e); - } - } - return stack; - } + ItemStack result = fake.getHeldItem(EnumHand.MAIN_HAND); + setHandItemWithoutAnnoyingSound(fake, EnumHand.MAIN_HAND, heldBefore); + return result; + } + } catch (Exception e) { + ModUtil.LOGGER.error("Something that places Blocks at " + offsetPos.getX() + ", " + offsetPos.getY() + ", " + offsetPos.getZ() + " in World " + world.provider.getDimension() + " threw an Exception! Don't let that happen again!", e); + } + } + return stack; + } - public static boolean dropItemAtSide(EnumFacing side, World world, BlockPos pos, ItemStack stack){ - BlockPos coords = pos.offset(side); - if(world.isBlockLoaded(coords)){ - EntityItem item = new EntityItem(world, coords.getX()+0.5, coords.getY()+0.5, coords.getZ()+0.5, stack); - item.motionX = 0; - item.motionY = 0; - item.motionZ = 0; + public static boolean dropItemAtSide(EnumFacing side, World world, BlockPos pos, ItemStack stack) { + BlockPos coords = pos.offset(side); + if (world.isBlockLoaded(coords)) { + EntityItem item = new EntityItem(world, coords.getX() + 0.5, coords.getY() + 0.5, coords.getZ() + 0.5, stack); + item.motionX = 0; + item.motionY = 0; + item.motionZ = 0; - return world.spawnEntity(item); - } - return false; - } + return world.spawnEntity(item); + } + return false; + } - public static EnumFacing getDirectionBySidesInOrder(int side){ - switch(side){ - case 0: - return EnumFacing.UP; - case 1: - return EnumFacing.DOWN; - case 2: - return EnumFacing.NORTH; - case 3: - return EnumFacing.EAST; - case 4: - return EnumFacing.SOUTH; - default: - return EnumFacing.WEST; - } - } + public static EnumFacing getDirectionBySidesInOrder(int side) { + switch (side) { + case 0: + return EnumFacing.UP; + case 1: + return EnumFacing.DOWN; + case 2: + return EnumFacing.NORTH; + case 3: + return EnumFacing.EAST; + case 4: + return EnumFacing.SOUTH; + default: + return EnumFacing.WEST; + } + } - public static EnumFacing getDirectionByPistonRotation(int meta){ - return EnumFacing.values()[meta]; - } + public static EnumFacing getDirectionByPistonRotation(int meta) { + return EnumFacing.values()[meta]; + } - public static ArrayList getMaterialsAround(World world, BlockPos pos){ - ArrayList blocks = new ArrayList(); - blocks.add(world.getBlockState(pos.offset(EnumFacing.NORTH)).getMaterial()); - blocks.add(world.getBlockState(pos.offset(EnumFacing.EAST)).getMaterial()); - blocks.add(world.getBlockState(pos.offset(EnumFacing.SOUTH)).getMaterial()); - blocks.add(world.getBlockState(pos.offset(EnumFacing.WEST)).getMaterial()); - return blocks; - } + public static ArrayList getMaterialsAround(World world, BlockPos pos) { + ArrayList blocks = new ArrayList(); + blocks.add(world.getBlockState(pos.offset(EnumFacing.NORTH)).getMaterial()); + blocks.add(world.getBlockState(pos.offset(EnumFacing.EAST)).getMaterial()); + blocks.add(world.getBlockState(pos.offset(EnumFacing.SOUTH)).getMaterial()); + blocks.add(world.getBlockState(pos.offset(EnumFacing.WEST)).getMaterial()); + return blocks; + } - public static boolean addToInventory(ItemStackHandlerCustom inventory, List stacks, boolean actuallyDo){ - return addToInventory(inventory, 0, inventory.getSlots(), stacks, actuallyDo); - } + public static boolean addToInventory(ItemStackHandlerCustom inventory, List stacks, boolean actuallyDo) { + return addToInventory(inventory, 0, inventory.getSlots(), stacks, actuallyDo); + } - public static boolean addToInventory(ItemStackHandlerCustom inventory, int start, int end, List stacks, boolean actuallyDo){ - //Copy the slots if just testing to later load them again - ItemStack[] backupSlots = null; - if(!actuallyDo){ - backupSlots = new ItemStack[inventory.getSlots()]; - for(int i = 0; i < backupSlots.length; i++){ - ItemStack stack = inventory.getStackInSlot(i); - backupSlots[i] = StackUtil.validateCopy(stack); - } - } + public static boolean addToInventory(ItemStackHandlerCustom inventory, int start, int end, List stacks, boolean actuallyDo) { + //Copy the slots if just testing to later load them again + ItemStack[] backupSlots = null; + if (!actuallyDo) { + backupSlots = new ItemStack[inventory.getSlots()]; + for (int i = 0; i < backupSlots.length; i++) { + ItemStack stack = inventory.getStackInSlot(i); + backupSlots[i] = StackUtil.validateCopy(stack); + } + } - int working = 0; - for(ItemStack stack : stacks){ - if(StackUtil.isValid(stack)){ - for(int i = start; i < end; i++){ - stack = inventory.insertItemInternal(i, stack, false); + int working = 0; + for (ItemStack stack : stacks) { + if (StackUtil.isValid(stack)) { + for (int i = start; i < end; i++) { + stack = inventory.insertItemInternal(i, stack, false); - if(!StackUtil.isValid(stack)){ - working++; - break; - } - } - } - else{ - working++; - } - } + if (!StackUtil.isValid(stack)) { + working++; + break; + } + } + } else { + working++; + } + } - //Load the slots again - if(!actuallyDo){ - for(int i = 0; i < backupSlots.length; i++){ - inventory.setStackInSlot(i, StackUtil.validateCheck(backupSlots[i])); - } - } + //Load the slots again + if (!actuallyDo) { + for (int i = 0; i < backupSlots.length; i++) { + inventory.setStackInSlot(i, StackUtil.validateCheck(backupSlots[i])); + } + } - return working >= stacks.size(); - } + return working >= stacks.size(); + } - public static int findFirstFilledSlot(ItemStackHandlerCustom slots){ - for(int i = 0; i < slots.getSlots(); i++){ - if(StackUtil.isValid(slots.getStackInSlot(i))){ - return i; - } - } - return 0; - } + public static int findFirstFilledSlot(ItemStackHandlerCustom slots) { + for (int i = 0; i < slots.getSlots(); i++) { + if (StackUtil.isValid(slots.getStackInSlot(i))) { return i; } + } + return 0; + } - public static RayTraceResult getNearestPositionWithAir(World world, EntityPlayer player, int reach){ - return getMovingObjectPosWithReachDistance(world, player, reach, false, false, true); - } + public static RayTraceResult getNearestPositionWithAir(World world, EntityPlayer player, int reach) { + return getMovingObjectPosWithReachDistance(world, player, reach, false, false, true); + } - private static RayTraceResult getMovingObjectPosWithReachDistance(World world, EntityPlayer player, double distance, boolean p1, boolean p2, boolean p3){ - float f = player.rotationPitch; - float f1 = player.rotationYaw; - double d0 = player.posX; - double d1 = player.posY+(double)player.getEyeHeight(); - double d2 = player.posZ; - Vec3d vec3 = new Vec3d(d0, d1, d2); - float f2 = MathHelper.cos(-f1*0.017453292F-(float)Math.PI); - float f3 = MathHelper.sin(-f1*0.017453292F-(float)Math.PI); - float f4 = -MathHelper.cos(-f*0.017453292F); - float f5 = MathHelper.sin(-f*0.017453292F); - float f6 = f3*f4; - float f7 = f2*f4; - Vec3d vec31 = vec3.addVector((double)f6*distance, (double)f5*distance, (double)f7*distance); - return world.rayTraceBlocks(vec3, vec31, p1, p2, p3); - } + private static RayTraceResult getMovingObjectPosWithReachDistance(World world, EntityPlayer player, double distance, boolean p1, boolean p2, boolean p3) { + float f = player.rotationPitch; + float f1 = player.rotationYaw; + double d0 = player.posX; + double d1 = player.posY + (double) player.getEyeHeight(); + double d2 = player.posZ; + Vec3d vec3 = new Vec3d(d0, d1, d2); + float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI); + float f3 = MathHelper.sin(-f1 * 0.017453292F - (float) Math.PI); + float f4 = -MathHelper.cos(-f * 0.017453292F); + float f5 = MathHelper.sin(-f * 0.017453292F); + float f6 = f3 * f4; + float f7 = f2 * f4; + Vec3d vec31 = vec3.addVector((double) f6 * distance, (double) f5 * distance, (double) f7 * distance); + return world.rayTraceBlocks(vec3, vec31, p1, p2, p3); + } - public static RayTraceResult getNearestBlockWithDefaultReachDistance(World world, EntityPlayer player){ - return getNearestBlockWithDefaultReachDistance(world, player, false, true, false); - } + public static RayTraceResult getNearestBlockWithDefaultReachDistance(World world, EntityPlayer player) { + return getNearestBlockWithDefaultReachDistance(world, player, false, true, false); + } - public static RayTraceResult getNearestBlockWithDefaultReachDistance(World world, EntityPlayer player, boolean stopOnLiquids, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock){ - return getMovingObjectPosWithReachDistance(world, player, player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(), stopOnLiquids, ignoreBlockWithoutBoundingBox, returnLastUncollidableBlock); - } + public static RayTraceResult getNearestBlockWithDefaultReachDistance(World world, EntityPlayer player, boolean stopOnLiquids, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock) { + return getMovingObjectPosWithReachDistance(world, player, player.getEntityAttribute(EntityPlayer.REACH_DISTANCE).getAttributeValue(), stopOnLiquids, ignoreBlockWithoutBoundingBox, returnLastUncollidableBlock); + } - //Cobbled together from Tinkers' Construct (with permission, thanks!) and PlayerInteractionManager code. - //Breaking blocks is a hideous pain so yea. - //This doesn't do any additional harvestability checks that the blocks itself don't do! - public static boolean playerHarvestBlock(ItemStack stack, World world, EntityPlayer player, BlockPos pos){ - if(world.isAirBlock(pos)){ - return false; - } + public static void setHandItemWithoutAnnoyingSound(EntityPlayer player, EnumHand hand, ItemStack stack) { + if (hand == EnumHand.MAIN_HAND) { + player.inventory.mainInventory.set(player.inventory.currentItem, stack); + } else if (hand == EnumHand.OFF_HAND) { + player.inventory.offHandInventory.set(0, stack); + } + } - IBlockState state = world.getBlockState(pos); - Block block = state.getBlock(); + public static float fireFakeHarvestEventsForDropChance(NonNullList drops, World world, BlockPos pos) { + if (world instanceof WorldServer) { + FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer) world); + IBlockState state = world.getBlockState(pos); - if(!world.isRemote){ - world.playEvent(player, 2001, pos, Block.getStateId(state)); - } - else{ - world.playEvent(2001, pos, Block.getStateId(state)); - } + BreakEvent event = new BreakEvent(world, pos, state, fake); + if (!MinecraftForge.EVENT_BUS.post(event)) { return ForgeEventFactory.fireBlockHarvesting(drops, world, pos, state, 0, 1, false, fake); } + } + return 0F; + } - if(player.capabilities.isCreativeMode){ + //Stolen from TiC - block.onBlockHarvested(world, pos, state, player); - if(block.removedByPlayer(state, world, pos, player, false)){ - block.onBlockDestroyedByPlayer(world, pos, state); - } + /** + * Returns true if the tool is effective for harvesting the given block. + */ + public static boolean isToolEffective(ItemStack stack, IBlockState state) { + // check material + for (String type : stack.getItem().getToolClasses(stack)) { + if (state.getBlock().isToolEffective(type, state)) { return true; } + } - if(!world.isRemote){ - if(player instanceof EntityPlayerMP){ - ((EntityPlayerMP)player).connection.sendPacket(new SPacketBlockChange(world, pos)); - } - } + return false; + } - return true; - } + public static boolean canBreakExtraBlock(ItemStack stack, World world, EntityPlayer player, BlockPos pos) { + // prevent calling that stuff for air blocks, could lead to unexpected behaviour since it fires events + if (world.isAirBlock(pos)) { return false; } - stack.onBlockDestroyed(world, state, pos, player); + // check if the block can be broken, since extra block breaks shouldn't instantly break stuff like obsidian + // or precious ores you can't harvest while mining stone + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); - if(!world.isRemote){ - if(player instanceof EntityPlayerMP){ - EntityPlayerMP playerMp = (EntityPlayerMP)player; + // only effective materials + if (!isToolEffective(stack, state)) { return false; } - int xp = ForgeHooks.onBlockBreakEvent(world, playerMp.interactionManager.getGameType(), playerMp, pos); - if(xp == -1){ - return false; - } + // only harvestable blocks that aren't impossibly slow to harvest + if (!ForgeHooks.canHarvestBlock(block, player, world, pos)) { return false; } - TileEntity tileEntity = world.getTileEntity(pos); - if(block.removedByPlayer(state, world, pos, player, true)){ - block.onBlockDestroyedByPlayer(world, pos, state); - block.harvestBlock(world, player, pos, state, tileEntity, stack); - block.dropXpOnBlockBreak(world, pos, xp); - } + // From this point on it's clear that the player CAN break the block - playerMp.connection.sendPacket(new SPacketBlockChange(world, pos)); - return true; - } - } - else{ - if(block.removedByPlayer(state, world, pos, player, true)){ - block.onBlockDestroyedByPlayer(world, pos, state); - } + return true; + } - if(StackUtil.getStackSize(stack) <= 0 && stack == player.getHeldItemMainhand()){ - ForgeEventFactory.onPlayerDestroyItem(player, stack, EnumHand.MAIN_HAND); - player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY); - } + public static boolean breakExtraBlock(ItemStack stack, World world, EntityPlayer player, BlockPos pos) { + IBlockState state = world.getBlockState(pos); + Block block = state.getBlock(); - if(ConfigBoolValues.ENABLE_DRILL_DIGGING_PACKET.isEnabled()){ - Minecraft mc = Minecraft.getMinecraft(); - mc.getConnection().sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, pos, mc.objectMouseOver.sideHit)); - } + if (player.capabilities.isCreativeMode) { + block.onBlockHarvested(world, pos, state, player); + if (block.removedByPlayer(state, world, pos, player, false)) { + block.onBlockDestroyedByPlayer(world, pos, state); + } - return true; - } - return false; - } + // send update to client + if (!world.isRemote) { + ((EntityPlayerMP) player).connection.sendPacket(new SPacketBlockChange(world, pos)); + } + return true; + } - public static float fireFakeHarvestEventsForDropChance(List drops, World world, BlockPos pos){ - if(!world.isRemote && world instanceof WorldServer){ - FakePlayer fake = FakePlayerFactory.getMinecraft((WorldServer)world); - IBlockState state = world.getBlockState(pos); + // callback to the tool the player uses. Called on both sides. This damages the tool n stuff. + stack.onBlockDestroyed(world, state, pos, player); - BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, fake); - if(!MinecraftForge.EVENT_BUS.post(event)){ - return ForgeEventFactory.fireBlockHarvesting(drops, world, pos, state, 0, 1, false, fake); - } - } - return 0F; - } + // server sided handling + if (!world.isRemote) { + // send the blockbreak event + int xp = ForgeHooks.onBlockBreakEvent(world, ((EntityPlayerMP) player).interactionManager.getGameType(), (EntityPlayerMP) player, pos); + if (xp == -1) { return false; } - public static void setHandItemWithoutAnnoyingSound(EntityPlayer player, EnumHand hand, ItemStack stack){ - if(hand == EnumHand.MAIN_HAND){ - player.inventory.mainInventory.set(player.inventory.currentItem, stack); - } - else if(hand == EnumHand.OFF_HAND){ - player.inventory.offHandInventory.set(0, stack); - } - } + // serverside we reproduce ItemInWorldManager.tryHarvestBlock + + TileEntity tileEntity = world.getTileEntity(pos); + // ItemInWorldManager.removeBlock + if (block.removedByPlayer(state, world, pos, player, true)) { // boolean is if block can be harvested, checked above + block.onBlockDestroyedByPlayer(world, pos, state); + block.harvestBlock(world, player, pos, state, tileEntity, stack); + block.dropXpOnBlockBreak(world, pos, xp); + } + + // always send block update to client + ((EntityPlayerMP) player).connection.sendPacket(new SPacketBlockChange(world, pos)); + return true; + } + // client sided handling + else { + // clientside we do a "this block has been clicked on long enough to be broken" call. This should not send any new packets + // the code above, executed on the server, sends a block-updates that give us the correct state of the block we destroy. + + // following code can be found in PlayerControllerMP.onPlayerDestroyBlock + world.playEvent(2001, pos, Block.getStateId(state)); + if (block.removedByPlayer(state, world, pos, player, true)) { + block.onBlockDestroyedByPlayer(world, pos, state); + } + // callback to the tool + stack.onBlockDestroyed(world, state, pos, player); + + // send an update to the server, so we get an update back + ActuallyAdditions.proxy.sendBreakPacket(pos); + return true; + } + } }