2015-08-29 14:33:25 +02:00
/ *
2016-05-16 22:52:27 +02:00
* This file ( " WorldUtil.java " ) is part of the Actually Additions mod for Minecraft .
2015-08-29 14:33:25 +02:00
* It is created and owned by Ellpeck and distributed
* under the Actually Additions License to be found at
2016-05-16 22:52:27 +02:00
* http : //ellpeck.de/actaddlicense
2015-08-29 14:33:25 +02:00
* View the source code at https : //github.com/Ellpeck/ActuallyAdditions
*
2016-05-16 22:54:42 +02:00
* © 2015 - 2016 Ellpeck
2015-08-29 14:33:25 +02:00
* /
2016-01-05 04:47:35 +01:00
package de.ellpeck.actuallyadditions.mod.util ;
2015-04-19 01:50:02 +02:00
2015-05-20 22:39:43 +02:00
import cofh.api.energy.EnergyStorage ;
2016-06-11 16:14:06 +02:00
import cofh.api.energy.IEnergyProvider ;
2015-05-20 22:39:43 +02:00
import cofh.api.energy.IEnergyReceiver ;
2015-05-30 17:47:57 +02:00
import net.minecraft.block.Block ;
2016-01-31 03:31:39 +01:00
import net.minecraft.block.BlockLiquid ;
2015-06-28 03:12:32 +02:00
import net.minecraft.block.material.Material ;
2016-01-08 08:18:27 +01:00
import net.minecraft.block.state.IBlockState ;
2015-07-27 08:26:13 +02:00
import net.minecraft.client.Minecraft ;
import net.minecraft.enchantment.EnchantmentHelper ;
2015-05-04 17:26:50 +02:00
import net.minecraft.entity.item.EntityItem ;
2015-07-07 20:20:24 +02:00
import net.minecraft.entity.player.EntityPlayer ;
2015-07-08 11:49:38 +02:00
import net.minecraft.entity.player.EntityPlayerMP ;
2015-05-30 17:47:57 +02:00
import net.minecraft.init.Blocks ;
2016-03-18 23:47:22 +01:00
import net.minecraft.init.Enchantments ;
2015-12-23 23:09:50 +01:00
import net.minecraft.init.Items ;
2015-12-08 18:10:37 +01:00
import net.minecraft.inventory.IInventory ;
2015-12-09 13:35:18 +01:00
import net.minecraft.inventory.ISidedInventory ;
2015-04-19 01:50:02 +02:00
import net.minecraft.item.ItemStack ;
2016-03-18 23:47:22 +01:00
import net.minecraft.network.play.client.CPacketPlayerDigging ;
import net.minecraft.network.play.server.SPacketBlockChange ;
2015-04-19 01:50:02 +02:00
import net.minecraft.tileentity.TileEntity ;
2016-05-01 10:33:40 +02:00
import net.minecraft.util.EnumFacing ;
2016-03-18 23:47:22 +01:00
import net.minecraft.util.math.BlockPos ;
import net.minecraft.util.math.MathHelper ;
import net.minecraft.util.math.RayTraceResult ;
import net.minecraft.util.math.Vec3d ;
2015-04-19 01:50:02 +02:00
import net.minecraft.world.World ;
2015-05-04 17:26:50 +02:00
import net.minecraft.world.WorldServer ;
2015-11-22 23:02:59 +01:00
import net.minecraftforge.common.ForgeHooks ;
2015-05-22 17:48:50 +02:00
import net.minecraftforge.common.IPlantable ;
2016-06-05 12:52:59 +02:00
import net.minecraftforge.fluids.FluidContainerRegistry ;
import net.minecraftforge.fluids.FluidStack ;
import net.minecraftforge.fluids.IFluidBlock ;
import net.minecraftforge.fluids.IFluidContainerItem ;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler ;
2016-06-05 02:16:52 +02:00
import net.minecraftforge.fluids.capability.IFluidHandler ;
2015-04-19 01:50:02 +02:00
2015-06-28 03:12:32 +02:00
import java.util.ArrayList ;
2016-05-04 13:15:30 +02:00
import java.util.List ;
2015-06-28 03:12:32 +02:00
2015-04-19 01:50:02 +02:00
public class WorldUtil {
2016-01-08 13:31:58 +01:00
public static void breakBlockAtSide ( EnumFacing side , World world , BlockPos pos ) {
2016-01-07 18:20:59 +01:00
breakBlockAtSide ( side , world , pos , 0 ) ;
2015-10-05 19:55:28 +02:00
}
2016-01-08 13:31:58 +01:00
public static void breakBlockAtSide ( EnumFacing side , World world , BlockPos pos , int offset ) {
2016-04-20 21:39:03 +02:00
world . setBlockToAir ( getCoordsFromSide ( side , pos , offset ) ) ;
2015-04-19 01:50:02 +02:00
}
2016-01-08 13:31:58 +01:00
public static BlockPos getCoordsFromSide ( EnumFacing side , BlockPos pos , int offset ) {
return new BlockPos ( pos . getX ( ) + side . getFrontOffsetX ( ) * ( offset + 1 ) , pos . getY ( ) + side . getFrontOffsetY ( ) * ( offset + 1 ) , pos . getZ ( ) + side . getFrontOffsetZ ( ) * ( offset + 1 ) ) ;
2015-10-03 10:19:40 +02:00
}
2016-01-17 19:22:14 +01:00
2016-06-11 16:14:06 +02:00
public static void pushEnergyToAllSides ( TileEntity tileFrom ) {
pushEnergy ( tileFrom , EnumFacing . UP ) ;
pushEnergy ( tileFrom , EnumFacing . DOWN ) ;
pushEnergy ( tileFrom , EnumFacing . NORTH ) ;
pushEnergy ( tileFrom , EnumFacing . EAST ) ;
pushEnergy ( tileFrom , EnumFacing . SOUTH ) ;
pushEnergy ( tileFrom , EnumFacing . WEST ) ;
2016-01-07 19:04:29 +01:00
}
2015-10-03 10:19:40 +02:00
2016-06-11 16:14:06 +02:00
public static void pushEnergy ( TileEntity tileFrom , EnumFacing side ) {
TileEntity tileTo = getTileEntityFromSide ( side , tileFrom . getWorld ( ) , tileFrom . getPos ( ) ) ;
if ( tileTo ! = null ) {
if ( tileFrom instanceof IEnergyProvider & & tileTo instanceof IEnergyReceiver ) {
IEnergyReceiver handlerTo = ( IEnergyReceiver ) tileTo ;
IEnergyProvider handlerFrom = ( IEnergyProvider ) tileFrom ;
int drain = handlerFrom . extractEnergy ( side , Integer . MAX_VALUE , true ) ;
if ( drain > 0 ) {
if ( handlerTo . canConnectEnergy ( side . getOpposite ( ) ) ) {
int filled = handlerTo . receiveEnergy ( side . getOpposite ( ) , drain , false ) ;
handlerFrom . extractEnergy ( side , filled , false ) ;
}
}
2015-05-20 22:39:43 +02:00
}
}
}
2016-01-08 13:31:58 +01:00
public static TileEntity getTileEntityFromSide ( EnumFacing side , World world , BlockPos pos ) {
BlockPos c = getCoordsFromSide ( side , pos , 0 ) ;
2016-05-16 22:52:27 +02:00
return world . getTileEntity ( c ) ;
2015-10-03 10:19:40 +02:00
}
2015-07-25 05:28:31 +02:00
/ * *
* Checks if a given Block with a given Meta is present in given Positions
2015-07-27 08:26:13 +02:00
*
2016-01-07 18:20:59 +01:00
* @param positions The Positions , an array of { xCoord , yCoord , zCoord } arrays containing Positions
2015-07-27 08:26:13 +02:00
* @param block The Block
* @param meta The Meta
* @param world The World
2015-07-25 05:28:31 +02:00
* @return Is every block present ?
* /
2016-01-08 13:31:58 +01:00
public static boolean hasBlocksInPlacesGiven ( BlockPos [ ] positions , Block block , int meta , World world ) {
for ( BlockPos pos : positions ) {
if ( ! ( PosUtil . getBlock ( pos , world ) = = block & & PosUtil . getMetadata ( pos , world ) = = meta ) ) {
2015-07-25 05:28:31 +02:00
return false ;
}
}
return true ;
}
2016-06-05 02:16:52 +02:00
public static void pushFluid ( TileEntity tileFrom , EnumFacing side ) {
TileEntity tileTo = getTileEntityFromSide ( side , tileFrom . getWorld ( ) , tileFrom . getPos ( ) ) ;
if ( tileTo ! = null ) {
2016-06-10 22:00:30 +02:00
if ( tileFrom instanceof net . minecraftforge . fluids . IFluidHandler & & tileTo instanceof net . minecraftforge . fluids . IFluidHandler ) {
net . minecraftforge . fluids . IFluidHandler handlerTo = ( net . minecraftforge . fluids . IFluidHandler ) tileTo ;
net . minecraftforge . fluids . IFluidHandler handlerFrom = ( net . minecraftforge . fluids . IFluidHandler ) tileFrom ;
FluidStack drain = handlerFrom . drain ( side , Integer . MAX_VALUE , false ) ;
2016-06-05 02:16:52 +02:00
if ( drain ! = null ) {
2016-06-10 22:00:30 +02:00
if ( handlerTo . canFill ( side . getOpposite ( ) , drain . getFluid ( ) ) ) {
int filled = handlerTo . fill ( side . getOpposite ( ) , drain . copy ( ) , true ) ;
handlerFrom . drain ( side , filled , true ) ;
}
}
}
else {
IFluidHandler handlerFrom = tileFrom . getCapability ( CapabilityFluidHandler . FLUID_HANDLER_CAPABILITY , side ) ;
IFluidHandler handlerTo = tileTo . getCapability ( CapabilityFluidHandler . FLUID_HANDLER_CAPABILITY , side . getOpposite ( ) ) ;
if ( handlerFrom ! = null & & handlerTo ! = null ) {
FluidStack drain = handlerFrom . drain ( Integer . MAX_VALUE , false ) ;
if ( drain ! = null ) {
int filled = handlerTo . fill ( drain . copy ( ) , true ) ;
handlerFrom . drain ( filled , true ) ;
}
2016-06-05 02:16:52 +02:00
}
2015-05-20 22:39:43 +02:00
}
}
}
2016-01-31 03:31:39 +01:00
public static ItemStack useItemAtSide ( EnumFacing side , World world , BlockPos pos , ItemStack stack ) {
2015-05-30 17:47:57 +02:00
if ( world instanceof WorldServer & & stack ! = null & & stack . getItem ( ) ! = null ) {
2016-01-08 13:31:58 +01:00
BlockPos offsetPos = pos . offset ( side ) ;
2016-01-31 03:31:39 +01:00
Block block = PosUtil . getBlock ( offsetPos , world ) ;
boolean replaceable = block . isReplaceable ( world , offsetPos ) ;
2015-05-27 21:57:53 +02:00
//Fluids
2016-05-06 23:23:29 +02:00
if ( replaceable & & ! ( block instanceof IFluidBlock ) & & ! ( block instanceof BlockLiquid ) ) {
FluidStack fluid = null ;
//TODO Remove when FluidContainerRegistry is gone
if ( FluidContainerRegistry . isFilledContainer ( stack ) ) {
2016-05-07 02:49:03 +02:00
fluid = FluidContainerRegistry . getFluidForFilledItem ( stack ) ;
2016-05-06 23:23:29 +02:00
}
else if ( stack . getItem ( ) instanceof IFluidContainerItem ) {
fluid = ( ( IFluidContainerItem ) stack . getItem ( ) ) . getFluid ( stack ) ;
}
if ( fluid ! = null & & fluid . amount > = Util . BUCKET & & fluid . getFluid ( ) . getBlock ( ) ! = null & & fluid . getFluid ( ) . getBlock ( ) . canPlaceBlockAt ( world , offsetPos ) ) {
2016-01-31 03:31:39 +01:00
if ( PosUtil . setBlock ( offsetPos , world , fluid . getFluid ( ) . getBlock ( ) , 0 , 2 ) ) {
2015-05-30 17:47:57 +02:00
return stack . getItem ( ) . getContainerItem ( stack ) ;
}
}
2015-05-27 21:57:53 +02:00
}
2015-12-23 23:09:50 +01:00
//Redstone
2016-05-12 18:48:13 +02:00
if ( replaceable & & stack . getItem ( ) = = Items . REDSTONE ) {
2016-04-20 21:39:03 +02:00
PosUtil . setBlock ( offsetPos , world , Blocks . REDSTONE_WIRE , 0 , 2 ) ;
2015-12-23 23:09:50 +01:00
stack . stackSize - - ;
2016-05-12 18:48:13 +02:00
return stack ;
2015-12-23 23:09:50 +01:00
}
2015-05-27 21:57:53 +02:00
//Plants
2016-05-12 18:48:13 +02:00
if ( replaceable & & stack . getItem ( ) instanceof IPlantable ) {
2016-01-07 21:41:28 +01:00
if ( ( ( IPlantable ) stack . getItem ( ) ) . getPlant ( world , offsetPos ) . getBlock ( ) . canPlaceBlockAt ( world , offsetPos ) ) {
2016-01-08 13:31:58 +01:00
if ( world . setBlockState ( offsetPos , ( ( IPlantable ) stack . getItem ( ) ) . getPlant ( world , offsetPos ) , 2 ) ) {
2015-05-30 17:47:57 +02:00
stack . stackSize - - ;
2016-05-12 18:48:13 +02:00
return stack ;
2015-05-30 17:47:57 +02:00
}
2015-05-22 17:48:50 +02:00
}
}
2016-01-31 03:31:39 +01:00
//Everything else
2016-05-12 18:48:13 +02:00
try {
EntityPlayer fake = FakePlayerUtil . getFakePlayer ( world ) ;
stack . onItemUse ( fake , world , offsetPos , fake . getActiveHand ( ) , side . getOpposite ( ) , 0 . 5F , 0 . 5F , 0 . 5F ) ;
return stack ;
}
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 ) ;
2015-05-30 17:47:57 +02:00
}
2015-04-19 01:50:02 +02:00
}
2015-05-30 17:47:57 +02:00
return stack ;
2015-04-19 01:50:02 +02:00
}
2016-01-08 13:31:58 +01:00
public static void dropItemAtSide ( EnumFacing side , World world , BlockPos pos , ItemStack stack ) {
BlockPos coords = getCoordsFromSide ( side , pos , 0 ) ;
2016-05-16 22:52:27 +02:00
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 ;
world . spawnEntityInWorld ( item ) ;
2015-05-04 17:26:50 +02:00
}
2016-01-07 18:20:59 +01:00
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 ;
2015-05-24 13:58:34 +02:00
}
2015-04-19 01:50:02 +02:00
}
2016-01-07 19:04:29 +01:00
public static EnumFacing getDirectionByPistonRotation ( int meta ) {
2016-01-08 13:31:58 +01:00
return EnumFacing . values ( ) [ meta ] ;
2016-01-07 19:04:29 +01:00
}
2016-01-08 13:31:58 +01:00
public static ArrayList < Material > getMaterialsAround ( World world , BlockPos pos ) {
2015-06-28 03:12:32 +02:00
ArrayList < Material > blocks = new ArrayList < Material > ( ) ;
2016-01-08 13:31:58 +01:00
blocks . add ( PosUtil . getMaterial ( pos . offset ( EnumFacing . NORTH ) , world ) ) ;
blocks . add ( PosUtil . getMaterial ( pos . offset ( EnumFacing . EAST ) , world ) ) ;
blocks . add ( PosUtil . getMaterial ( pos . offset ( EnumFacing . SOUTH ) , world ) ) ;
blocks . add ( PosUtil . getMaterial ( pos . offset ( EnumFacing . WEST ) , world ) ) ;
2015-06-28 03:12:32 +02:00
return blocks ;
}
2016-05-04 13:15:30 +02:00
public static boolean addToInventory ( IInventory inventory , List < ItemStack > stacks , boolean actuallyDo , boolean shouldAlwaysWork ) {
2016-02-01 17:49:55 +01:00
return addToInventory ( inventory , stacks , EnumFacing . UP , actuallyDo , shouldAlwaysWork ) ;
}
2016-05-04 13:15:30 +02:00
public static boolean addToInventory ( IInventory inventory , List < ItemStack > stacks , EnumFacing side , boolean actuallyDo , boolean shouldAlwaysWork ) {
2016-02-01 17:49:55 +01:00
return addToInventory ( inventory , 0 , inventory . getSizeInventory ( ) , stacks , side , actuallyDo , shouldAlwaysWork ) ;
}
2015-10-05 11:27:53 +02:00
/ * *
* Add an ArrayList of ItemStacks to an Array of slots
2015-10-05 19:55:28 +02:00
*
2015-12-08 18:10:37 +01:00
* @param inventory The inventory to try to put the items into
2015-10-05 19:55:28 +02:00
* @param stacks The stacks to be put into the slots ( Items don ' t actually get removed from there ! )
2016-01-07 18:20:59 +01:00
* @param side The side to input from
2015-10-05 11:27:53 +02:00
* @param actuallyDo Do it or just test if it works ?
* @return Does it work ?
* /
2016-05-04 13:15:30 +02:00
public static boolean addToInventory ( IInventory inventory , int start , int end , List < ItemStack > stacks , EnumFacing side , boolean actuallyDo , boolean shouldAlwaysWork ) {
2015-12-08 18:10:37 +01:00
//Copy the slots if just testing to later load them again
ItemStack [ ] backupSlots = null ;
if ( ! actuallyDo ) {
backupSlots = new ItemStack [ inventory . getSizeInventory ( ) ] ;
for ( int i = 0 ; i < backupSlots . length ; i + + ) {
ItemStack stack = inventory . getStackInSlot ( i ) ;
if ( stack ! = null ) {
backupSlots [ i ] = stack . copy ( ) ;
2015-10-10 02:51:06 +02:00
}
2015-10-05 11:27:53 +02:00
}
}
2015-07-07 12:32:25 +02:00
int working = 0 ;
2015-10-05 11:27:53 +02:00
for ( ItemStack stackToPutIn : stacks ) {
2015-10-10 02:51:06 +02:00
for ( int i = start ; i < end ; i + + ) {
2016-01-07 18:20:59 +01:00
if ( shouldAlwaysWork | | ( ( ! ( inventory instanceof ISidedInventory ) | | ( ( ISidedInventory ) inventory ) . canInsertItem ( i , stackToPutIn , side ) ) & & inventory . isItemValidForSlot ( i , stackToPutIn ) ) ) {
2015-12-09 13:35:18 +01:00
ItemStack stackInQuestion = inventory . getStackInSlot ( i ) ;
if ( stackToPutIn ! = null & & ( stackInQuestion = = null | | ( stackInQuestion . isItemEqual ( stackToPutIn ) & & stackInQuestion . getMaxStackSize ( ) > = stackInQuestion . stackSize + stackToPutIn . stackSize ) ) ) {
if ( stackInQuestion = = null ) {
inventory . setInventorySlotContents ( i , stackToPutIn . copy ( ) ) ;
}
else {
stackInQuestion . stackSize + = stackToPutIn . stackSize ;
}
working + + ;
2015-10-05 11:27:53 +02:00
2015-12-09 13:35:18 +01:00
break ;
}
2015-07-07 12:32:25 +02:00
}
}
}
2015-12-08 18:10:37 +01:00
//Load the slots again
2016-05-16 22:52:27 +02:00
if ( ! actuallyDo ) {
2015-12-08 18:10:37 +01:00
for ( int i = 0 ; i < backupSlots . length ; i + + ) {
inventory . setInventorySlotContents ( i , backupSlots [ i ] ) ;
}
}
2015-07-07 12:32:25 +02:00
return working > = stacks . size ( ) ;
}
2015-07-07 12:34:20 +02:00
public static int findFirstFilledSlot ( ItemStack [ ] slots ) {
2015-07-07 12:32:25 +02:00
for ( int i = 0 ; i < slots . length ; i + + ) {
if ( slots [ i ] ! = null ) {
return i ;
}
}
return 0 ;
}
2015-07-07 20:20:24 +02:00
2016-03-18 23:47:22 +01:00
public static RayTraceResult getNearestPositionWithAir ( World world , EntityPlayer player , int reach ) {
2015-07-08 11:49:38 +02:00
return getMovingObjectPosWithReachDistance ( world , player , reach , false , false , true ) ;
}
2016-03-18 23:47:22 +01:00
private static RayTraceResult getMovingObjectPosWithReachDistance ( World world , EntityPlayer player , double distance , boolean p1 , boolean p2 , boolean p3 ) {
2016-01-17 19:22:14 +01:00
float f = player . rotationPitch ;
float f1 = player . rotationYaw ;
double d0 = player . posX ;
double d1 = player . posY + ( double ) player . getEyeHeight ( ) ;
double d2 = player . posZ ;
2016-03-18 23:47:22 +01:00
Vec3d vec3 = new Vec3d ( d0 , d1 , d2 ) ;
2016-01-17 19:22:14 +01:00
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 ;
2016-03-18 23:47:22 +01:00
Vec3d vec31 = vec3 . addVector ( ( double ) f6 * distance , ( double ) f5 * distance , ( double ) f7 * distance ) ;
2016-01-07 18:20:59 +01:00
return world . rayTraceBlocks ( vec3 , vec31 , p1 , p2 , p3 ) ;
2015-07-07 20:20:24 +02:00
}
2015-07-27 08:26:13 +02:00
2016-03-18 23:47:22 +01:00
public static RayTraceResult getNearestBlockWithDefaultReachDistance ( World world , EntityPlayer player ) {
2016-06-02 19:28:51 +02:00
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 instanceof EntityPlayerMP ? ( ( EntityPlayerMP ) player ) . interactionManager . getBlockReachDistance ( ) : 5 . 0D , stopOnLiquids , ignoreBlockWithoutBoundingBox , returnLastUncollidableBlock ) ;
2015-10-03 10:19:40 +02:00
}
2015-07-27 08:26:13 +02:00
/ * *
* Harvests a Block by a Player
*
* @param world The World
* @param player The Player
* @return If the Block could be harvested normally ( so that it drops an item )
* /
2016-01-08 13:31:58 +01:00
public static boolean playerHarvestBlock ( World world , BlockPos pos , EntityPlayer player ) {
IBlockState state = world . getBlockState ( pos ) ;
2016-06-11 23:43:28 +02:00
if ( state = = null ) {
return false ;
}
Block block = state . getBlock ( ) ;
if ( block = = null ) {
return false ;
}
2016-01-08 13:31:58 +01:00
TileEntity tile = world . getTileEntity ( pos ) ;
2016-05-02 07:50:13 +02:00
ItemStack stack = player . getHeldItemMainhand ( ) ;
2016-03-18 23:47:22 +01:00
2015-07-27 08:26:13 +02:00
//If the Block can be harvested or not
2016-01-07 19:47:53 +01:00
boolean canHarvest = block . canHarvestBlock ( world , pos , player ) ;
2015-07-27 08:26:13 +02:00
2015-11-22 23:02:59 +01:00
//Send Block Breaking Event
2016-05-01 10:33:40 +02:00
int xp = - 1 ;
2015-11-22 23:02:59 +01:00
if ( player instanceof EntityPlayerMP ) {
2016-06-11 23:43:28 +02:00
EntityPlayerMP playerMP = ( EntityPlayerMP ) player ;
xp = ForgeHooks . onBlockBreakEvent ( world , playerMP . interactionManager . getGameType ( ) , playerMP , pos ) ;
2016-05-01 10:33:40 +02:00
if ( xp = = - 1 ) {
2015-11-22 23:02:59 +01:00
return false ;
}
}
2015-07-27 08:26:13 +02:00
if ( ! world . isRemote ) {
//Server-Side only, special cases
2016-01-08 08:18:27 +01:00
block . onBlockHarvested ( world , pos , state , player ) ;
2015-07-27 08:26:13 +02:00
}
else {
//Shows the Harvest Particles and plays the Block's Sound
2016-06-03 21:05:49 +02:00
world . playEvent ( 2001 , pos , Block . getStateId ( state ) ) ;
2015-07-27 08:26:13 +02:00
}
//If the Block was actually "removed", meaning it will drop an Item
2016-03-18 23:47:22 +01:00
boolean removed = block . removedByPlayer ( state , world , pos , player , canHarvest ) ;
2015-07-27 08:26:13 +02:00
//Actually removes the Block from the World
if ( removed ) {
//Before the Block is destroyed, special cases
2016-01-08 08:18:27 +01:00
block . onBlockDestroyedByPlayer ( world , pos , state ) ;
2015-07-27 08:26:13 +02:00
if ( ! world . isRemote & & ! player . capabilities . isCreativeMode ) {
//Actually drops the Block's Items etc.
if ( canHarvest ) {
2016-03-18 23:47:22 +01:00
block . harvestBlock ( world , player , pos , state , tile , stack ) ;
2015-07-27 08:26:13 +02:00
}
//Only drop XP when no Silk Touch is applied
2016-04-20 21:39:03 +02:00
if ( EnchantmentHelper . getEnchantmentLevel ( Enchantments . SILK_TOUCH , stack ) < = 0 ) {
2016-05-01 10:33:40 +02:00
if ( xp > = 0 ) {
block . dropXpOnBlockBreak ( world , pos , xp ) ;
}
2015-07-27 08:26:13 +02:00
}
}
}
if ( ! world . isRemote ) {
//Update the Client of a Block Change
2015-11-22 23:02:59 +01:00
if ( player instanceof EntityPlayerMP ) {
2016-05-19 20:05:12 +02:00
( ( EntityPlayerMP ) player ) . connection . sendPacket ( new SPacketBlockChange ( world , pos ) ) ;
2015-11-22 23:02:59 +01:00
}
2015-07-27 08:26:13 +02:00
}
else {
//Check the Server if a Block that changed on the Client really changed, if not, revert the change
2016-05-19 20:05:12 +02:00
Minecraft . getMinecraft ( ) . getConnection ( ) . sendPacket ( new CPacketPlayerDigging ( CPacketPlayerDigging . Action . STOP_DESTROY_BLOCK , pos , Minecraft . getMinecraft ( ) . objectMouseOver . sideHit ) ) ;
2015-07-27 08:26:13 +02:00
}
2016-06-11 23:43:28 +02:00
2015-07-27 08:26:13 +02:00
return removed ;
}
2015-04-19 01:50:02 +02:00
}