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
*
2017-01-01 16:23:26 +01:00
* © 2015 - 2017 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
2016-07-25 02:07:16 +02:00
import de.ellpeck.actuallyadditions.mod.ActuallyAdditions ;
2017-01-21 15:22:26 +01:00
import de.ellpeck.actuallyadditions.mod.config.values.ConfigBoolValues ;
2017-02-04 14:12:17 +01:00
import de.ellpeck.actuallyadditions.mod.tile.FilterSettings ;
import de.ellpeck.actuallyadditions.mod.util.compat.SlotlessableItemHandlerWrapper ;
2016-06-17 14:00:52 +02:00
import de.ellpeck.actuallyadditions.mod.util.compat.TeslaUtil ;
2016-11-26 20:43:50 +01:00
import net.darkhax.tesla.api.ITeslaConsumer ;
import net.darkhax.tesla.api.ITeslaProducer ;
2015-05-30 17:47:57 +02:00
import net.minecraft.block.Block ;
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 ;
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 ;
2015-12-23 23:09:50 +01:00
import net.minecraft.init.Items ;
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-07-06 18:31:29 +02:00
import net.minecraft.util.EnumHand ;
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 ;
2017-02-04 16:07:58 +01:00
import net.minecraftforge.common.MinecraftForge ;
2016-06-19 20:24:13 +02:00
import net.minecraftforge.common.util.FakePlayer ;
import net.minecraftforge.common.util.FakePlayerFactory ;
2016-11-26 08:58:42 +01:00
import net.minecraftforge.energy.CapabilityEnergy ;
import net.minecraftforge.energy.IEnergyStorage ;
2016-07-06 18:31:29 +02:00
import net.minecraftforge.event.ForgeEventFactory ;
2017-02-04 16:07:58 +01:00
import net.minecraftforge.event.world.BlockEvent ;
2016-11-19 21:11:17 +01:00
import net.minecraftforge.fluids.FluidStack ;
2016-06-05 12:52:59 +02:00
import net.minecraftforge.fluids.capability.CapabilityFluidHandler ;
2016-06-05 02:16:52 +02:00
import net.minecraftforge.fluids.capability.IFluidHandler ;
2016-07-20 22:14:30 +02:00
import net.minecraftforge.items.IItemHandler ;
2017-02-04 14:12:17 +01:00
import org.cyclops.commoncapabilities.api.capability.itemhandler.ISlotlessItemHandler ;
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
2016-06-17 13:25:15 +02:00
public final class WorldUtil {
2015-04-19 01:50:02 +02:00
2017-02-04 14:12:17 +01:00
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 ) {
2017-05-28 01:26:08 +02:00
return doItemInteraction ( extractWrapper , insertWrapper , maxExtract , 0 , Integer . MAX_VALUE , 0 , Integer . MAX_VALUE , filter ) ;
2017-02-04 14:12:17 +01:00
}
2017-05-28 01:26:08 +02:00
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 ) ;
2016-12-18 13:27:14 +01:00
if ( StackUtil . isValid ( theoreticalExtract ) ) {
2017-05-28 01:26:08 +02:00
ItemStack remaining = insertItem ( insertWrapper , theoreticalExtract , false , insertSlotStart , insertSlotEnd ) ;
2016-12-18 13:27:14 +01:00
if ( ! ItemStack . areItemStacksEqual ( remaining , theoreticalExtract ) ) {
int toExtract = ! StackUtil . isValid ( remaining ) ? StackUtil . getStackSize ( theoreticalExtract ) : StackUtil . getStackSize ( theoreticalExtract ) - StackUtil . getStackSize ( remaining ) ;
2017-05-28 01:26:08 +02:00
extractItem ( extractWrapper , toExtract , false , extractSlotStart , extractSlotEnd , filter ) ;
2016-12-18 13:27:14 +01:00
return true ;
2016-07-20 22:14:30 +02:00
}
}
2016-11-02 19:40:48 +01:00
return false ;
2016-07-20 22:14:30 +02:00
}
2017-02-04 14:12:17 +01:00
public static ItemStack extractItem ( SlotlessableItemHandlerWrapper extractWrapper , int maxExtract , boolean simulate , int slotStart , int slotEnd , FilterSettings filter ) {
ItemStack extracted = StackUtil . getNull ( ) ;
if ( ActuallyAdditions . commonCapsLoaded ) {
Object handler = extractWrapper . getSlotlessHandler ( ) ;
if ( handler instanceof ISlotlessItemHandler ) {
ISlotlessItemHandler slotless = ( ISlotlessItemHandler ) handler ;
2017-02-04 16:32:20 +01:00
if ( filter = = null | | ! filter . needsCheck ( ) ) {
2017-02-04 14:12:17 +01:00
extracted = slotless . extractItem ( maxExtract , simulate ) ;
2017-02-04 16:32:20 +01:00
return extracted ;
2017-02-04 14:12:17 +01:00
}
else {
ItemStack would = slotless . extractItem ( maxExtract , true ) ;
if ( filter . check ( would ) ) {
if ( simulate ) {
extracted = would ;
}
else {
extracted = slotless . extractItem ( maxExtract , false ) ;
}
}
2017-02-04 16:32:20 +01:00
//Leave the possibility to fall back to vanilla when there is a filter
2017-02-04 14:12:17 +01:00
}
}
}
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 + + ) {
2017-02-04 16:32:20 +01:00
if ( filter = = null | | ! filter . needsCheck ( ) | | filter . check ( handler . getStackInSlot ( i ) ) ) {
2017-02-04 14:12:17 +01:00
extracted = handler . extractItem ( i , maxExtract , simulate ) ;
if ( StackUtil . isValid ( extracted ) ) {
break ;
}
}
}
}
}
return extracted ;
}
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 ) ;
2017-02-04 16:32:20 +01:00
if ( ! ItemStack . areItemStacksEqual ( remain , stack ) ) {
return remain ;
}
2017-02-04 14:12:17 +01:00
}
}
2017-02-04 16:32:20 +01:00
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 ) ;
2017-02-04 14:12:17 +01:00
}
}
return remain ;
}
2016-09-09 18:40:09 +02:00
public static void doEnergyInteraction ( TileEntity tileFrom , TileEntity tileTo , EnumFacing sideTo , int maxTransfer ) {
2016-08-31 21:14:48 +02:00
if ( maxTransfer > 0 ) {
2016-12-18 17:28:29 +01:00
EnumFacing opp = sideTo = = null ? null : sideTo . getOpposite ( ) ;
if ( tileFrom . hasCapability ( CapabilityEnergy . ENERGY , sideTo ) & & tileTo . hasCapability ( CapabilityEnergy . ENERGY , opp ) ) {
2016-11-26 08:58:42 +01:00
IEnergyStorage handlerFrom = tileFrom . getCapability ( CapabilityEnergy . ENERGY , sideTo ) ;
2016-12-18 17:28:29 +01:00
IEnergyStorage handlerTo = tileTo . getCapability ( CapabilityEnergy . ENERGY , opp ) ;
2016-11-26 08:58:42 +01:00
if ( handlerFrom ! = null & & handlerTo ! = null ) {
int drain = handlerFrom . extractEnergy ( maxTransfer , true ) ;
if ( drain > 0 ) {
int filled = handlerTo . receiveEnergy ( drain , false ) ;
handlerFrom . extractEnergy ( filled , false ) ;
2016-11-26 19:00:02 +01:00
return ;
2016-11-26 08:58:42 +01:00
}
}
2016-06-17 13:25:15 +02:00
}
2016-11-26 19:00:02 +01:00
if ( ActuallyAdditions . teslaLoaded ) {
2016-12-18 17:28:29 +01:00
if ( tileTo . hasCapability ( TeslaUtil . teslaConsumer , opp ) & & tileFrom . hasCapability ( TeslaUtil . teslaProducer , sideTo ) ) {
ITeslaConsumer handlerTo = tileTo . getCapability ( TeslaUtil . teslaConsumer , opp ) ;
2016-11-26 20:43:50 +01:00
ITeslaProducer handlerFrom = tileFrom . getCapability ( TeslaUtil . teslaProducer , sideTo ) ;
if ( handlerTo ! = null & & handlerFrom ! = null ) {
long drain = handlerFrom . takePower ( maxTransfer , true ) ;
if ( drain > 0 ) {
long filled = handlerTo . givePower ( drain , false ) ;
handlerFrom . takePower ( filled , false ) ;
}
}
}
2016-11-26 19:00:02 +01:00
}
2016-06-17 13:25:15 +02:00
}
2016-01-07 19:04:29 +01:00
}
2015-10-03 10:19:40 +02:00
2016-09-09 18:40:09 +02:00
public static void doFluidInteraction ( TileEntity tileFrom , TileEntity tileTo , EnumFacing sideTo , int maxTransfer ) {
2016-08-31 21:14:48 +02:00
if ( maxTransfer > 0 ) {
2016-11-19 21:11:17 +01:00
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 ) ;
2016-09-09 18:40:09 +02:00
if ( drain ! = null ) {
2016-11-19 21:11:17 +01:00
int filled = handlerTo . fill ( drain . copy ( ) , true ) ;
handlerFrom . drain ( filled , true ) ;
2016-06-11 16:14:06 +02:00
}
2015-05-20 22:39:43 +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
*
2017-06-29 18:30:02 +02:00
* @param positions The Positions , an array of { x , y , z } 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 ) {
2016-07-04 20:15:41 +02:00
IBlockState state = world . getBlockState ( pos ) ;
if ( ! ( state . getBlock ( ) = = block & & block . getMetaFromState ( state ) = = meta ) ) {
2015-07-25 05:28:31 +02:00
return false ;
}
}
return true ;
}
2016-01-31 03:31:39 +01:00
public static ItemStack useItemAtSide ( EnumFacing side , World world , BlockPos pos , ItemStack stack ) {
2016-11-16 16:59:00 +01:00
if ( world instanceof WorldServer & & StackUtil . isValid ( stack ) & & pos ! = null ) {
2016-01-08 13:31:58 +01:00
BlockPos offsetPos = pos . offset ( side ) ;
2016-07-04 20:15:41 +02:00
IBlockState state = world . getBlockState ( offsetPos ) ;
Block block = state . getBlock ( ) ;
2016-01-31 03:31:39 +01:00
boolean replaceable = block . isReplaceable ( world , offsetPos ) ;
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-07-04 20:15:41 +02:00
world . setBlockState ( offsetPos , Blocks . REDSTONE_WIRE . getDefaultState ( ) , 2 ) ;
2016-11-16 16:59:00 +01:00
return StackUtil . addStackSize ( stack , - 1 ) ;
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 ) ) {
2016-11-16 16:59:00 +01:00
return StackUtil . addStackSize ( stack , - 1 ) ;
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 {
2016-06-19 20:24:13 +02:00
if ( world instanceof WorldServer ) {
FakePlayer fake = FakePlayerFactory . getMinecraft ( ( WorldServer ) world ) ;
2016-12-05 14:11:20 +01:00
ItemStack heldBefore = fake . getHeldItemMainhand ( ) ;
2017-02-06 14:01:11 +01:00
setHandItemWithoutAnnoyingSound ( fake , EnumHand . MAIN_HAND , stack . copy ( ) ) ;
2016-12-05 14:11:20 +01:00
fake . getHeldItemMainhand ( ) . onItemUse ( fake , world , offsetPos , fake . getActiveHand ( ) , side . getOpposite ( ) , 0 . 5F , 0 . 5F , 0 . 5F ) ;
ItemStack result = fake . getHeldItem ( EnumHand . MAIN_HAND ) ;
2017-02-06 14:01:11 +01:00
setHandItemWithoutAnnoyingSound ( fake , EnumHand . MAIN_HAND , heldBefore ) ;
2016-12-05 14:11:20 +01:00
return result ;
2016-06-19 20:24:13 +02:00
}
2016-05-12 18:48:13 +02:00
}
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-12-08 14:25:16 +01:00
public static boolean dropItemAtSide ( EnumFacing side , World world , BlockPos pos , ItemStack stack ) {
2016-07-04 20:15:41 +02:00
BlockPos coords = pos . offset ( side ) ;
2016-12-08 14:25:16 +01:00
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 ;
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-07-04 20:15:41 +02:00
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 ( ) ) ;
2015-06-28 03:12:32 +02:00
return blocks ;
}
2016-12-04 00:10:52 +01:00
public static boolean addToInventory ( ItemStackHandlerCustom inventory , List < ItemStack > stacks , boolean actuallyDo ) {
return addToInventory ( inventory , 0 , inventory . getSlots ( ) , stacks , actuallyDo ) ;
2016-02-01 17:49:55 +01:00
}
2016-12-04 00:10:52 +01:00
public static boolean addToInventory ( ItemStackHandlerCustom inventory , int start , int end , List < ItemStack > stacks , boolean actuallyDo ) {
2015-12-08 18:10:37 +01:00
//Copy the slots if just testing to later load them again
ItemStack [ ] backupSlots = null ;
if ( ! actuallyDo ) {
2016-12-04 00:10:52 +01:00
backupSlots = new ItemStack [ inventory . getSlots ( ) ] ;
2015-12-08 18:10:37 +01:00
for ( int i = 0 ; i < backupSlots . length ; i + + ) {
ItemStack stack = inventory . getStackInSlot ( i ) ;
2016-11-20 20:13:26 +01:00
backupSlots [ i ] = StackUtil . validateCopy ( stack ) ;
2015-10-05 11:27:53 +02:00
}
}
2015-07-07 12:32:25 +02:00
int working = 0 ;
2016-12-04 00:10:52 +01:00
for ( ItemStack stack : stacks ) {
2016-12-27 10:33:13 +01:00
if ( StackUtil . isValid ( stack ) ) {
for ( int i = start ; i < end ; i + + ) {
stack = inventory . insertItemInternal ( i , stack , false ) ;
2015-10-05 11:27:53 +02:00
2016-12-27 10:33:13 +01:00
if ( ! StackUtil . isValid ( stack ) ) {
working + + ;
break ;
}
2015-07-07 12:32:25 +02:00
}
}
2016-12-27 10:33:13 +01:00
else {
working + + ;
}
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 + + ) {
2016-12-27 10:33:13 +01:00
inventory . setStackInSlot ( i , StackUtil . validateCheck ( backupSlots [ i ] ) ) ;
2015-12-08 18:10:37 +01:00
}
}
2015-07-07 12:32:25 +02:00
return working > = stacks . size ( ) ;
}
2016-12-04 00:10:52 +01:00
public static int findFirstFilledSlot ( ItemStackHandlerCustom slots ) {
for ( int i = 0 ; i < slots . getSlots ( ) ; i + + ) {
if ( StackUtil . isValid ( slots . getStackInSlot ( i ) ) ) {
2015-07-07 12:32:25 +02:00
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
}
2016-07-06 18:31:29 +02:00
//Cobbled together from Tinkers' Construct (with permission, thanks!) and PlayerInteractionManager code.
//Breaking blocks is a hideous pain so yea.
2016-07-07 20:17:09 +02:00
//This doesn't do any additional harvestability checks that the blocks itself don't do!
2016-07-06 18:31:29 +02:00
public static boolean playerHarvestBlock ( ItemStack stack , World world , EntityPlayer player , BlockPos pos ) {
if ( world . isAirBlock ( pos ) ) {
2016-06-11 23:43:28 +02:00
return false ;
}
2016-07-06 18:31:29 +02:00
IBlockState state = world . getBlockState ( pos ) ;
2016-06-11 23:43:28 +02:00
Block block = state . getBlock ( ) ;
2016-07-06 18:31:29 +02:00
2016-07-19 09:15:09 +02:00
if ( ! world . isRemote ) {
world . playEvent ( player , 2001 , pos , Block . getStateId ( state ) ) ;
}
else {
world . playEvent ( 2001 , pos , Block . getStateId ( state ) ) ;
}
2016-07-06 18:31:29 +02:00
if ( player . capabilities . isCreativeMode ) {
2016-07-19 09:15:09 +02:00
2016-07-06 18:31:29 +02:00
block . onBlockHarvested ( world , pos , state , player ) ;
if ( block . removedByPlayer ( state , world , pos , player , false ) ) {
block . onBlockDestroyedByPlayer ( world , pos , state ) ;
}
2015-07-27 08:26:13 +02:00
2016-07-06 18:42:17 +02:00
if ( ! world . isRemote ) {
if ( player instanceof EntityPlayerMP ) {
( ( EntityPlayerMP ) player ) . connection . sendPacket ( new SPacketBlockChange ( world , pos ) ) ;
}
2015-11-22 23:02:59 +01:00
}
2016-07-06 18:42:17 +02:00
2016-07-06 18:31:29 +02:00
return true ;
2015-11-22 23:02:59 +01:00
}
2016-07-06 18:31:29 +02:00
stack . onBlockDestroyed ( world , state , pos , player ) ;
2015-07-27 08:26:13 +02:00
if ( ! world . isRemote ) {
2016-07-06 18:31:29 +02:00
if ( player instanceof EntityPlayerMP ) {
EntityPlayerMP playerMp = ( EntityPlayerMP ) player ;
2015-07-27 08:26:13 +02:00
2016-07-06 18:31:29 +02:00
int xp = ForgeHooks . onBlockBreakEvent ( world , playerMp . interactionManager . getGameType ( ) , playerMp , pos ) ;
if ( xp = = - 1 ) {
return false ;
2015-07-27 08:26:13 +02:00
}
2016-07-06 18:31:29 +02:00
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 ) ;
2015-07-27 08:26:13 +02:00
}
2016-07-06 18:31:29 +02:00
playerMp . connection . sendPacket ( new SPacketBlockChange ( world , pos ) ) ;
2016-07-06 18:42:17 +02:00
return true ;
2015-11-22 23:02:59 +01:00
}
2015-07-27 08:26:13 +02:00
}
else {
2016-07-06 18:31:29 +02:00
if ( block . removedByPlayer ( state , world , pos , player , true ) ) {
block . onBlockDestroyedByPlayer ( world , pos , state ) ;
}
2016-11-16 16:59:00 +01:00
if ( StackUtil . getStackSize ( stack ) < = 0 & & stack = = player . getHeldItemMainhand ( ) ) {
2016-07-06 18:31:29 +02:00
ForgeEventFactory . onPlayerDestroyItem ( player , stack , EnumHand . MAIN_HAND ) ;
player . setHeldItem ( EnumHand . MAIN_HAND , null ) ;
}
2017-01-21 15:22:26 +01:00
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 ) ) ;
}
2016-07-06 18:42:17 +02:00
return true ;
2016-07-06 18:31:29 +02:00
}
2016-07-06 18:42:17 +02:00
return false ;
2015-07-27 08:26:13 +02:00
}
2017-02-04 16:07:58 +01:00
public static float fireFakeHarvestEventsForDropChance ( List < ItemStack > drops , World world , BlockPos pos ) {
if ( ! world . isRemote & & world instanceof WorldServer ) {
FakePlayer fake = FakePlayerFactory . getMinecraft ( ( WorldServer ) world ) ;
IBlockState state = world . getBlockState ( pos ) ;
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 ;
}
2017-02-06 14:01:11 +01:00
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 ) ;
}
}
2015-04-19 01:50:02 +02:00
}