aboutsummaryrefslogtreecommitdiffhomepage
path: root/patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch')
-rw-r--r--patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch695
1 files changed, 695 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch
new file mode 100644
index 0000000000..41bb7ef0b3
--- /dev/null
+++ b/patch-remap/mache-vineflower/net/minecraft/world/level/block/Block.java.patch
@@ -0,0 +1,695 @@
+--- a/net/minecraft/world/level/block/Block.java
++++ b/net/minecraft/world/level/block/Block.java
+@@ -7,6 +7,7 @@
+ import com.mojang.logging.LogUtils;
+ import com.mojang.serialization.MapCodec;
+ import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap;
++import java.util.Iterator;
+ import java.util.List;
+ import java.util.function.Function;
+ import java.util.function.Supplier;
+@@ -43,14 +44,14 @@
+ import net.minecraft.world.level.BlockGetter;
+ import net.minecraft.world.level.Explosion;
+ import net.minecraft.world.level.GameRules;
+-import net.minecraft.world.level.ItemLike;
++import net.minecraft.world.level.IMaterial;
+ import net.minecraft.world.level.Level;
+ import net.minecraft.world.level.LevelAccessor;
+ import net.minecraft.world.level.LevelReader;
+ import net.minecraft.world.level.biome.Biome;
+ import net.minecraft.world.level.block.entity.BlockEntity;
+ import net.minecraft.world.level.block.state.BlockBehaviour;
+-import net.minecraft.world.level.block.state.BlockState;
++import net.minecraft.world.level.block.state.IBlockData;
+ import net.minecraft.world.level.block.state.StateDefinition;
+ import net.minecraft.world.level.block.state.properties.Property;
+ import net.minecraft.world.level.gameevent.GameEvent;
+@@ -62,20 +63,17 @@
+ import net.minecraft.world.phys.shapes.VoxelShape;
+ import org.slf4j.Logger;
+
+-public class Block extends BlockBehaviour implements ItemLike {
++public class Block extends BlockBehaviour implements IMaterial {
++
+ public static final MapCodec<Block> CODEC = simpleCodec(Block::new);
+ private static final Logger LOGGER = LogUtils.getLogger();
+- private final Holder.Reference<Block> builtInRegistryHolder = BuiltInRegistries.BLOCK.createIntrusiveHolder(this);
+- public static final IdMapper<BlockState> BLOCK_STATE_REGISTRY = new IdMapper<>();
+- private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder()
+- .maximumSize(512L)
+- .weakKeys()
+- .build(new CacheLoader<VoxelShape, Boolean>() {
+- @Override
+- public Boolean load(VoxelShape shape) {
+- return !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME);
+- }
+- });
++ private final Holder.Reference<Block> builtInRegistryHolder;
++ public static final IdMapper<IBlockData> BLOCK_STATE_REGISTRY = new IdMapper<>();
++ private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().build(new CacheLoader<VoxelShape, Boolean>() {
++ public Boolean load(VoxelShape voxelshape) {
++ return !Shapes.joinIsNotEmpty(Shapes.block(), voxelshape, BooleanOp.NOT_SAME);
++ }
++ });
+ public static final int UPDATE_NEIGHBORS = 1;
+ public static final int UPDATE_CLIENTS = 2;
+ public static final int UPDATE_INVISIBLE = 4;
+@@ -89,143 +87,156 @@
+ public static final float INDESTRUCTIBLE = -1.0F;
+ public static final float INSTANT = 0.0F;
+ public static final int UPDATE_LIMIT = 512;
+- protected final StateDefinition<Block, BlockState> stateDefinition;
+- private BlockState defaultBlockState;
++ protected final StateDefinition<Block, IBlockData> stateDefinition;
++ private IBlockData defaultBlockState;
+ @Nullable
+ private String descriptionId;
+ @Nullable
+ private Item item;
+ private static final int CACHE_SIZE = 2048;
+ private static final ThreadLocal<Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey>> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> {
+- Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey> map = new Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey>(2048, 0.25F) {
+- @Override
+- protected void rehash(int newN) {
+- }
++ Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey> object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey>(2048, 0.25F) {
++ protected void rehash(int i) {}
+ };
+- map.defaultReturnValue((byte)127);
+- return map;
++
++ object2bytelinkedopenhashmap.defaultReturnValue((byte) 127);
++ return object2bytelinkedopenhashmap;
+ });
+
+ @Override
+ protected MapCodec<? extends Block> codec() {
+- return CODEC;
++ return Block.CODEC;
+ }
+
+- public static int getId(@Nullable BlockState state) {
++ public static int getId(@Nullable IBlockData state) {
+ if (state == null) {
+ return 0;
+ } else {
+- int id = BLOCK_STATE_REGISTRY.getId(state);
+- return id == -1 ? 0 : id;
++ int i = Block.BLOCK_STATE_REGISTRY.getId(state);
++
++ return i == -1 ? 0 : i;
+ }
+ }
+
+- public static BlockState stateById(int id) {
+- BlockState blockState = BLOCK_STATE_REGISTRY.byId(id);
+- return blockState == null ? Blocks.AIR.defaultBlockState() : blockState;
++ public static IBlockData stateById(int id) {
++ IBlockData iblockdata = (IBlockData) Block.BLOCK_STATE_REGISTRY.byId(id);
++
++ return iblockdata == null ? Blocks.AIR.defaultBlockState() : iblockdata;
+ }
+
+ public static Block byItem(@Nullable Item item) {
+- return item instanceof BlockItem ? ((BlockItem)item).getBlock() : Blocks.AIR;
++ return item instanceof BlockItem ? ((BlockItem) item).getBlock() : Blocks.AIR;
+ }
+
+- public static BlockState pushEntitiesUp(BlockState oldState, BlockState newState, LevelAccessor level, BlockPos pos) {
+- VoxelShape voxelShape = Shapes.joinUnoptimized(oldState.getCollisionShape(level, pos), newState.getCollisionShape(level, pos), BooleanOp.ONLY_SECOND)
+- .move((double)pos.getX(), (double)pos.getY(), (double)pos.getZ());
+- if (voxelShape.isEmpty()) {
++ public static IBlockData pushEntitiesUp(IBlockData oldState, IBlockData newState, LevelAccessor level, BlockPos pos) {
++ VoxelShape voxelshape = Shapes.joinUnoptimized(oldState.getCollisionShape(level, pos), newState.getCollisionShape(level, pos), BooleanOp.ONLY_SECOND).move((double) pos.getX(), (double) pos.getY(), (double) pos.getZ());
++
++ if (voxelshape.isEmpty()) {
+ return newState;
+ } else {
+- for (Entity entity : level.getEntities(null, voxelShape.bounds())) {
+- double d = Shapes.collide(Direction.Axis.Y, entity.getBoundingBox().move(0.0, 1.0, 0.0), List.of(voxelShape), -1.0);
+- entity.teleportRelative(0.0, 1.0 + d, 0.0);
++ List<Entity> list = level.getEntities((Entity) null, voxelshape.bounds());
++ Iterator iterator = list.iterator();
++
++ while (iterator.hasNext()) {
++ Entity entity = (Entity) iterator.next();
++ double d0 = Shapes.collide(Direction.Axis.Y, entity.getBoundingBox().move(0.0D, 1.0D, 0.0D), List.of(voxelshape), -1.0D);
++
++ entity.teleportRelative(0.0D, 1.0D + d0, 0.0D);
+ }
+
+ return newState;
+ }
+ }
+
+- public static VoxelShape box(double x1, double y1, double z1, double x2, double y2, double z2) {
+- return Shapes.box(x1 / 16.0, y1 / 16.0, z1 / 16.0, x2 / 16.0, y2 / 16.0, z2 / 16.0);
++ public static VoxelShape box(double x1, double d1, double y1, double d3, double z1, double d5) {
++ return Shapes.box(x1 / 16.0D, d1 / 16.0D, y1 / 16.0D, d3 / 16.0D, z1 / 16.0D, d5 / 16.0D);
+ }
+
+- public static BlockState updateFromNeighbourShapes(BlockState currentState, LevelAccessor level, BlockPos pos) {
+- BlockState blockState = currentState;
+- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
++ public static IBlockData updateFromNeighbourShapes(IBlockData currentState, LevelAccessor level, BlockPos pos) {
++ IBlockData iblockdata1 = currentState;
++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
++ Direction[] aenumdirection = Block.UPDATE_SHAPE_ORDER;
++ int i = aenumdirection.length;
+
+- for (Direction direction : UPDATE_SHAPE_ORDER) {
+- mutableBlockPos.setWithOffset(pos, direction);
+- blockState = blockState.updateShape(direction, level.getBlockState(mutableBlockPos), level, pos, mutableBlockPos);
++ for (int j = 0; j < i; ++j) {
++ Direction enumdirection = aenumdirection[j];
++
++ blockposition_mutableblockposition.setWithOffset(pos, enumdirection);
++ iblockdata1 = iblockdata1.updateShape(enumdirection, level.getBlockState(blockposition_mutableblockposition), level, pos, blockposition_mutableblockposition);
+ }
+
+- return blockState;
++ return iblockdata1;
+ }
+
+- public static void updateOrDestroy(BlockState oldState, BlockState newState, LevelAccessor level, BlockPos pos, int flags) {
++ public static void updateOrDestroy(IBlockData oldState, IBlockData newState, LevelAccessor level, BlockPos pos, int flags) {
+ updateOrDestroy(oldState, newState, level, pos, flags, 512);
+ }
+
+- public static void updateOrDestroy(BlockState oldState, BlockState newState, LevelAccessor level, BlockPos pos, int flags, int recursionLeft) {
++ public static void updateOrDestroy(IBlockData oldState, IBlockData newState, LevelAccessor level, BlockPos pos, int flags, int recursionLeft) {
+ if (newState != oldState) {
+ if (newState.isAir()) {
+ if (!level.isClientSide()) {
+- level.destroyBlock(pos, (flags & 32) == 0, null, recursionLeft);
++ level.destroyBlock(pos, (flags & 32) == 0, (Entity) null, recursionLeft);
+ }
+ } else {
+ level.setBlock(pos, newState, flags & -33, recursionLeft);
+ }
+ }
++
+ }
+
+ public Block(BlockBehaviour.Properties properties) {
+ super(properties);
+- StateDefinition.Builder<Block, BlockState> builder = new StateDefinition.Builder<>(this);
+- this.createBlockStateDefinition(builder);
+- this.stateDefinition = builder.create(Block::defaultBlockState, BlockState::new);
+- this.registerDefaultState(this.stateDefinition.any());
++ this.builtInRegistryHolder = BuiltInRegistries.BLOCK.createIntrusiveHolder(this);
++ StateDefinition.Builder<Block, IBlockData> blockstatelist_a = new StateDefinition.Builder<>(this);
++
++ this.createBlockStateDefinition(blockstatelist_a);
++ this.stateDefinition = blockstatelist_a.create(Block::defaultBlockState, IBlockData::new);
++ this.registerDefaultState((IBlockData) this.stateDefinition.any());
+ if (SharedConstants.IS_RUNNING_IN_IDE) {
+- String simpleName = this.getClass().getSimpleName();
+- if (!simpleName.endsWith("Block")) {
+- LOGGER.error("Block classes should end with Block and {} doesn't.", simpleName);
++ String s = this.getClass().getSimpleName();
++
++ if (!s.endsWith("Block")) {
++ Block.LOGGER.error("Block classes should end with Block and {} doesn't.", s);
+ }
+ }
++
+ }
+
+- public static boolean isExceptionForConnection(BlockState state) {
+- return state.getBlock() instanceof LeavesBlock
+- || state.is(Blocks.BARRIER)
+- || state.is(Blocks.CARVED_PUMPKIN)
+- || state.is(Blocks.JACK_O_LANTERN)
+- || state.is(Blocks.MELON)
+- || state.is(Blocks.PUMPKIN)
+- || state.is(BlockTags.SHULKER_BOXES);
++ public static boolean isExceptionForConnection(IBlockData state) {
++ return state.getBlock() instanceof LeavesBlock || state.is(Blocks.BARRIER) || state.is(Blocks.CARVED_PUMPKIN) || state.is(Blocks.JACK_O_LANTERN) || state.is(Blocks.MELON) || state.is(Blocks.PUMPKIN) || state.is(BlockTags.SHULKER_BOXES);
+ }
+
+- public boolean isRandomlyTicking(BlockState state) {
++ public boolean isRandomlyTicking(IBlockData state) {
+ return this.isRandomlyTicking;
+ }
+
+- public static boolean shouldRenderFace(BlockState state, BlockGetter level, BlockPos offset, Direction face, BlockPos pos) {
+- BlockState blockState = level.getBlockState(pos);
+- if (state.skipRendering(blockState, face)) {
++ public static boolean shouldRenderFace(IBlockData state, BlockGetter level, BlockPos offset, Direction face, BlockPos pos) {
++ IBlockData iblockdata1 = level.getBlockState(pos);
++
++ if (state.skipRendering(iblockdata1, face)) {
+ return false;
+- } else if (blockState.canOcclude()) {
+- Block.BlockStatePairKey blockStatePairKey = new Block.BlockStatePairKey(state, blockState, face);
+- Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey> map = OCCLUSION_CACHE.get();
+- byte andMoveToFirst = map.getAndMoveToFirst(blockStatePairKey);
+- if (andMoveToFirst != 127) {
+- return andMoveToFirst != 0;
++ } else if (iblockdata1.canOcclude()) {
++ Block.BlockStatePairKey block_a = new Block.BlockStatePairKey(state, iblockdata1, face);
++ Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey> object2bytelinkedopenhashmap = (Object2ByteLinkedOpenHashMap) Block.OCCLUSION_CACHE.get();
++ byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a);
++
++ if (b0 != 127) {
++ return b0 != 0;
+ } else {
+- VoxelShape faceOcclusionShape = state.getFaceOcclusionShape(level, offset, face);
+- if (faceOcclusionShape.isEmpty()) {
++ VoxelShape voxelshape = state.getFaceOcclusionShape(level, offset, face);
++
++ if (voxelshape.isEmpty()) {
+ return true;
+ } else {
+- VoxelShape faceOcclusionShape1 = blockState.getFaceOcclusionShape(level, pos, face.getOpposite());
+- boolean flag = Shapes.joinIsNotEmpty(faceOcclusionShape, faceOcclusionShape1, BooleanOp.ONLY_FIRST);
+- if (map.size() == 2048) {
+- map.removeLastByte();
++ VoxelShape voxelshape1 = iblockdata1.getFaceOcclusionShape(level, pos, face.getOpposite());
++ boolean flag = Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.ONLY_FIRST);
++
++ if (object2bytelinkedopenhashmap.size() == 2048) {
++ object2bytelinkedopenhashmap.removeLastByte();
+ }
+
+- map.putAndMoveToFirst(blockStatePairKey, (byte)(flag ? 1 : 0));
++ object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0));
+ return flag;
+ }
+ }
+@@ -239,132 +250,144 @@
+ }
+
+ public static boolean canSupportCenter(LevelReader level, BlockPos pos, Direction direction) {
+- BlockState blockState = level.getBlockState(pos);
+- return (direction != Direction.DOWN || !blockState.is(BlockTags.UNSTABLE_BOTTOM_CENTER))
+- && blockState.isFaceSturdy(level, pos, direction, SupportType.CENTER);
++ IBlockData iblockdata = level.getBlockState(pos);
++
++ return direction == Direction.DOWN && iblockdata.is(BlockTags.UNSTABLE_BOTTOM_CENTER) ? false : iblockdata.isFaceSturdy(level, pos, direction, SupportType.CENTER);
+ }
+
+ public static boolean isFaceFull(VoxelShape shape, Direction face) {
+- VoxelShape faceShape = shape.getFaceShape(face);
+- return isShapeFullBlock(faceShape);
++ VoxelShape voxelshape1 = shape.getFaceShape(face);
++
++ return isShapeFullBlock(voxelshape1);
+ }
+
+ public static boolean isShapeFullBlock(VoxelShape shape) {
+- return SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
++ return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape);
+ }
+
+- public boolean propagatesSkylightDown(BlockState state, BlockGetter level, BlockPos pos) {
++ public boolean propagatesSkylightDown(IBlockData state, BlockGetter level, BlockPos pos) {
+ return !isShapeFullBlock(state.getShape(level, pos)) && state.getFluidState().isEmpty();
+ }
+
+- public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
+- }
++ public void animateTick(IBlockData state, Level level, BlockPos pos, RandomSource random) {}
+
+- public void destroy(LevelAccessor level, BlockPos pos, BlockState state) {
+- }
++ public void destroy(LevelAccessor level, BlockPos pos, IBlockData state) {}
+
+- public static List<ItemStack> getDrops(BlockState state, ServerLevel level, BlockPos pos, @Nullable BlockEntity blockEntity) {
+- LootParams.Builder builder = new LootParams.Builder(level)
+- .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
+- .withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
+- .withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity);
+- return state.getDrops(builder);
++ public static List<ItemStack> getDrops(IBlockData state, ServerLevel level, BlockPos pos, @Nullable BlockEntity blockEntity) {
++ LootParams.Builder lootparams_a = (new LootParams.Builder(level)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity);
++
++ return state.getDrops(lootparams_a);
+ }
+
+- public static List<ItemStack> getDrops(
+- BlockState state, ServerLevel level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool
+- ) {
+- LootParams.Builder builder = new LootParams.Builder(level)
+- .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
+- .withParameter(LootContextParams.TOOL, tool)
+- .withOptionalParameter(LootContextParams.THIS_ENTITY, entity)
+- .withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity);
+- return state.getDrops(builder);
++ public static List<ItemStack> getDrops(IBlockData state, ServerLevel level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
++ LootParams.Builder lootparams_a = (new LootParams.Builder(level)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)).withParameter(LootContextParams.TOOL, tool).withOptionalParameter(LootContextParams.THIS_ENTITY, entity).withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity);
++
++ return state.getDrops(lootparams_a);
+ }
+
+- public static void dropResources(BlockState state, Level level, BlockPos pos) {
++ public static void dropResources(IBlockData state, Level level, BlockPos pos) {
+ if (level instanceof ServerLevel) {
+- getDrops(state, (ServerLevel)level, pos, null).forEach(itemStack -> popResource(level, pos, itemStack));
+- state.spawnAfterBreak((ServerLevel)level, pos, ItemStack.EMPTY, true);
++ getDrops(state, (ServerLevel) level, pos, (BlockEntity) null).forEach((itemstack) -> {
++ popResource(level, pos, itemstack);
++ });
++ state.spawnAfterBreak((ServerLevel) level, pos, ItemStack.EMPTY, true);
+ }
++
+ }
+
+- public static void dropResources(BlockState state, LevelAccessor level, BlockPos pos, @Nullable BlockEntity blockEntity) {
++ public static void dropResources(IBlockData state, LevelAccessor level, BlockPos pos, @Nullable BlockEntity blockEntity) {
+ if (level instanceof ServerLevel) {
+- getDrops(state, (ServerLevel)level, pos, blockEntity).forEach(itemStack -> popResource((ServerLevel)level, pos, itemStack));
+- state.spawnAfterBreak((ServerLevel)level, pos, ItemStack.EMPTY, true);
++ getDrops(state, (ServerLevel) level, pos, blockEntity).forEach((itemstack) -> {
++ popResource((ServerLevel) level, pos, itemstack);
++ });
++ state.spawnAfterBreak((ServerLevel) level, pos, ItemStack.EMPTY, true);
+ }
++
+ }
+
+- public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
++ public static void dropResources(IBlockData state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
+ if (level instanceof ServerLevel) {
+- getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(itemStack -> popResource(level, pos, itemStack));
+- state.spawnAfterBreak((ServerLevel)level, pos, tool, true);
++ getDrops(state, (ServerLevel) level, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
++ popResource(level, pos, itemstack1);
++ });
++ state.spawnAfterBreak((ServerLevel) level, pos, tool, true);
+ }
++
+ }
+
+ public static void popResource(Level level, BlockPos pos, ItemStack stack) {
+- double d = (double)EntityType.ITEM.getHeight() / 2.0;
+- double d1 = (double)pos.getX() + 0.5 + Mth.nextDouble(level.random, -0.25, 0.25);
+- double d2 = (double)pos.getY() + 0.5 + Mth.nextDouble(level.random, -0.25, 0.25) - d;
+- double d3 = (double)pos.getZ() + 0.5 + Mth.nextDouble(level.random, -0.25, 0.25);
+- popResource(level, () -> new ItemEntity(level, d1, d2, d3, stack), stack);
++ double d0 = (double) EntityType.ITEM.getHeight() / 2.0D;
++ double d1 = (double) pos.getX() + 0.5D + Mth.nextDouble(level.random, -0.25D, 0.25D);
++ double d2 = (double) pos.getY() + 0.5D + Mth.nextDouble(level.random, -0.25D, 0.25D) - d0;
++ double d3 = (double) pos.getZ() + 0.5D + Mth.nextDouble(level.random, -0.25D, 0.25D);
++
++ popResource(level, () -> {
++ return new ItemEntity(level, d1, d2, d3, stack);
++ }, stack);
+ }
+
+ public static void popResourceFromFace(Level level, BlockPos pos, Direction direction, ItemStack stack) {
+- int stepX = direction.getStepX();
+- int stepY = direction.getStepY();
+- int stepZ = direction.getStepZ();
+- double d = (double)EntityType.ITEM.getWidth() / 2.0;
+- double d1 = (double)EntityType.ITEM.getHeight() / 2.0;
+- double d2 = (double)pos.getX() + 0.5 + (stepX == 0 ? Mth.nextDouble(level.random, -0.25, 0.25) : (double)stepX * (0.5 + d));
+- double d3 = (double)pos.getY() + 0.5 + (stepY == 0 ? Mth.nextDouble(level.random, -0.25, 0.25) : (double)stepY * (0.5 + d1)) - d1;
+- double d4 = (double)pos.getZ() + 0.5 + (stepZ == 0 ? Mth.nextDouble(level.random, -0.25, 0.25) : (double)stepZ * (0.5 + d));
+- double d5 = stepX == 0 ? Mth.nextDouble(level.random, -0.1, 0.1) : (double)stepX * 0.1;
+- double d6 = stepY == 0 ? Mth.nextDouble(level.random, 0.0, 0.1) : (double)stepY * 0.1 + 0.1;
+- double d7 = stepZ == 0 ? Mth.nextDouble(level.random, -0.1, 0.1) : (double)stepZ * 0.1;
+- popResource(level, () -> new ItemEntity(level, d2, d3, d4, stack, d5, d6, d7), stack);
++ int i = direction.getStepX();
++ int j = direction.getStepY();
++ int k = direction.getStepZ();
++ double d0 = (double) EntityType.ITEM.getWidth() / 2.0D;
++ double d1 = (double) EntityType.ITEM.getHeight() / 2.0D;
++ double d2 = (double) pos.getX() + 0.5D + (i == 0 ? Mth.nextDouble(level.random, -0.25D, 0.25D) : (double) i * (0.5D + d0));
++ double d3 = (double) pos.getY() + 0.5D + (j == 0 ? Mth.nextDouble(level.random, -0.25D, 0.25D) : (double) j * (0.5D + d1)) - d1;
++ double d4 = (double) pos.getZ() + 0.5D + (k == 0 ? Mth.nextDouble(level.random, -0.25D, 0.25D) : (double) k * (0.5D + d0));
++ double d5 = i == 0 ? Mth.nextDouble(level.random, -0.1D, 0.1D) : (double) i * 0.1D;
++ double d6 = j == 0 ? Mth.nextDouble(level.random, 0.0D, 0.1D) : (double) j * 0.1D + 0.1D;
++ double d7 = k == 0 ? Mth.nextDouble(level.random, -0.1D, 0.1D) : (double) k * 0.1D;
++
++ popResource(level, () -> {
++ return new ItemEntity(level, d2, d3, d4, stack, d5, d6, d7);
++ }, stack);
+ }
+
+ private static void popResource(Level level, Supplier<ItemEntity> itemEntitySupplier, ItemStack stack) {
+ if (!level.isClientSide && !stack.isEmpty() && level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
+- ItemEntity itemEntity = itemEntitySupplier.get();
+- itemEntity.setDefaultPickUpDelay();
+- level.addFreshEntity(itemEntity);
++ ItemEntity entityitem = (ItemEntity) itemEntitySupplier.get();
++
++ entityitem.setDefaultPickUpDelay();
++ // CraftBukkit start
++ if (level.captureDrops != null) {
++ level.captureDrops.add(entityitem);
++ } else {
++ level.addFreshEntity(entityitem);
++ }
++ // CraftBukkit end
+ }
+ }
+
+- protected void popExperience(ServerLevel level, BlockPos pos, int amount) {
++ public void popExperience(ServerLevel level, BlockPos pos, int amount) {
+ if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
+ ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount);
+ }
++
+ }
+
+ public float getExplosionResistance() {
+ return this.explosionResistance;
+ }
+
+- public void wasExploded(Level level, BlockPos pos, Explosion explosion) {
+- }
++ public void wasExploded(Level level, BlockPos pos, Explosion explosion) {}
+
+- public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) {
+- }
++ public void stepOn(Level level, BlockPos pos, IBlockData state, Entity entity) {}
+
+ @Nullable
+- public BlockState getStateForPlacement(BlockPlaceContext context) {
++ public IBlockData getStateForPlacement(BlockPlaceContext context) {
+ return this.defaultBlockState();
+ }
+
+- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
++ public void playerDestroy(Level level, Player player, BlockPos pos, IBlockData state, @Nullable BlockEntity blockEntity, ItemStack tool) {
+ player.awardStat(Stats.BLOCK_MINED.get(this));
+- player.causeFoodExhaustion(0.005F);
++ player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
+ dropResources(state, level, pos, blockEntity, player, tool);
+ }
+
+- public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
+- }
++ public void setPlacedBy(Level level, BlockPos pos, IBlockData state, @Nullable LivingEntity placer, ItemStack stack) {}
+
+- public boolean isPossibleToRespawnInThis(BlockState state) {
++ public boolean isPossibleToRespawnInThis(IBlockData state) {
+ return !state.isSolid() && !state.liquid();
+ }
+
+@@ -380,15 +403,15 @@
+ return this.descriptionId;
+ }
+
+- public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
++ public void fallOn(Level level, IBlockData state, BlockPos pos, Entity entity, float fallDistance) {
+ entity.causeFallDamage(fallDistance, 1.0F, entity.damageSources().fall());
+ }
+
+ public void updateEntityAfterFallOn(BlockGetter level, Entity entity) {
+- entity.setDeltaMovement(entity.getDeltaMovement().multiply(1.0, 0.0, 1.0));
++ entity.setDeltaMovement(entity.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
+ }
+
+- public ItemStack getCloneItemStack(LevelReader levelReader, BlockPos blockPos, BlockState blockState) {
++ public ItemStack getCloneItemStack(LevelReader iworldreader, BlockPos blockposition, IBlockData iblockdata) {
+ return new ItemStack(this);
+ }
+
+@@ -404,59 +427,60 @@
+ return this.jumpFactor;
+ }
+
+- protected void spawnDestroyParticles(Level level, Player player, BlockPos pos, BlockState state) {
++ protected void spawnDestroyParticles(Level level, Player player, BlockPos pos, IBlockData state) {
+ level.levelEvent(player, 2001, pos, getId(state));
+ }
+
+- public BlockState playerWillDestroy(Level level, BlockPos blockPos, BlockState blockState, Player player) {
+- this.spawnDestroyParticles(level, player, blockPos, blockState);
+- if (blockState.is(BlockTags.GUARDED_BY_PIGLINS)) {
+- PiglinAi.angerNearbyPiglins(player, false);
++ public IBlockData playerWillDestroy(Level world, BlockPos blockposition, IBlockData iblockdata, Player entityhuman) {
++ this.spawnDestroyParticles(world, entityhuman, blockposition, iblockdata);
++ if (iblockdata.is(BlockTags.GUARDED_BY_PIGLINS)) {
++ PiglinAi.angerNearbyPiglins(entityhuman, false);
+ }
+
+- level.gameEvent(GameEvent.BLOCK_DESTROY, blockPos, GameEvent.Context.of(player, blockState));
+- return blockState;
++ world.gameEvent(GameEvent.BLOCK_DESTROY, blockposition, GameEvent.Context.of(entityhuman, iblockdata));
++ return iblockdata;
+ }
+
+- public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) {
+- }
++ public void handlePrecipitation(IBlockData state, Level level, BlockPos pos, Biome.Precipitation precipitation) {}
+
+ public boolean dropFromExplosion(Explosion explosion) {
+ return true;
+ }
+
+- protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
+- }
++ protected void createBlockStateDefinition(StateDefinition.Builder<Block, IBlockData> builder) {}
+
+- public StateDefinition<Block, BlockState> getStateDefinition() {
++ public StateDefinition<Block, IBlockData> getStateDefinition() {
+ return this.stateDefinition;
+ }
+
+- protected final void registerDefaultState(BlockState state) {
++ protected final void registerDefaultState(IBlockData state) {
+ this.defaultBlockState = state;
+ }
+
+- public final BlockState defaultBlockState() {
++ public final IBlockData defaultBlockState() {
+ return this.defaultBlockState;
+ }
+
+- public final BlockState withPropertiesOf(BlockState state) {
+- BlockState blockState = this.defaultBlockState();
++ public final IBlockData withPropertiesOf(IBlockData state) {
++ IBlockData iblockdata1 = this.defaultBlockState();
++ Iterator iterator = state.getBlock().getStateDefinition().getProperties().iterator();
+
+- for (Property<?> property : state.getBlock().getStateDefinition().getProperties()) {
+- if (blockState.hasProperty(property)) {
+- blockState = copyProperty(state, blockState, property);
++ while (iterator.hasNext()) {
++ Property<?> iblockstate = (Property) iterator.next();
++
++ if (iblockdata1.hasProperty(iblockstate)) {
++ iblockdata1 = copyProperty(state, iblockdata1, iblockstate);
+ }
+ }
+
+- return blockState;
++ return iblockdata1;
+ }
+
+- private static <T extends Comparable<T>> BlockState copyProperty(BlockState sourceState, BlockState targetState, Property<T> property) {
+- return targetState.setValue(property, sourceState.getValue(property));
++ private static <T extends Comparable<T>> IBlockData copyProperty(IBlockData sourceState, IBlockData targetState, Property<T> property) {
++ return (IBlockData) targetState.setValue(property, sourceState.getValue(property));
+ }
+
+- public SoundType getSoundType(BlockState state) {
++ public SoundType getSoundType(IBlockData state) {
+ return this.soundType;
+ }
+
+@@ -473,62 +497,76 @@
+ return this.dynamicShape;
+ }
+
+- @Override
+ public String toString() {
+ return "Block{" + BuiltInRegistries.BLOCK.getKey(this) + "}";
+ }
+
+- public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List<Component> tooltip, TooltipFlag flag) {
+- }
++ public void appendHoverText(ItemStack stack, @Nullable BlockGetter level, List<Component> tooltip, TooltipFlag flag) {}
+
+ @Override
+ protected Block asBlock() {
+ return this;
+ }
+
+- protected ImmutableMap<BlockState, VoxelShape> getShapeForEachState(Function<BlockState, VoxelShape> shapeGetter) {
+- return this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), shapeGetter));
++ protected ImmutableMap<IBlockData, VoxelShape> getShapeForEachState(Function<IBlockData, VoxelShape> shapeGetter) {
++ return (ImmutableMap) this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), shapeGetter));
+ }
+
++ /** @deprecated */
+ @Deprecated
+ public Holder.Reference<Block> builtInRegistryHolder() {
+ return this.builtInRegistryHolder;
+ }
+
+- protected void tryDropExperience(ServerLevel level, BlockPos pos, ItemStack heldItem, IntProvider amount) {
+- if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, heldItem) == 0) {
+- int i = amount.sample(level.random);
++ // CraftBukkit start
++ protected int tryDropExperience(ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, IntProvider intprovider) {
++ if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) {
++ int i = intprovider.sample(worldserver.random);
++
+ if (i > 0) {
+- this.popExperience(level, pos, i);
++ // this.popExperience(worldserver, blockposition, i);
++ return i;
+ }
+ }
++
++ return 0;
+ }
+
++ public int getExpDrop(IBlockData iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
++ return 0;
++ }
++ // CraftBukkit end
++
+ public static final class BlockStatePairKey {
+- private final BlockState first;
+- private final BlockState second;
++
++ private final IBlockData first;
++ private final IBlockData second;
+ private final Direction direction;
+
+- public BlockStatePairKey(BlockState first, BlockState second, Direction direction) {
++ public BlockStatePairKey(IBlockData first, IBlockData second, Direction direction) {
+ this.first = first;
+ this.second = second;
+ this.direction = direction;
+ }
+
+- @Override
+- public boolean equals(Object other) {
+- return this == other
+- || other instanceof Block.BlockStatePairKey blockStatePairKey
+- && this.first == blockStatePairKey.first
+- && this.second == blockStatePairKey.second
+- && this.direction == blockStatePairKey.direction;
++ public boolean equals(Object object) {
++ if (this == object) {
++ return true;
++ } else if (!(object instanceof Block.BlockStatePairKey)) {
++ return false;
++ } else {
++ Block.BlockStatePairKey block_a = (Block.BlockStatePairKey) object;
++
++ return this.first == block_a.first && this.second == block_a.second && this.direction == block_a.direction;
++ }
+ }
+
+- @Override
+ public int hashCode() {
+- int hashCode = this.first.hashCode();
+- hashCode = 31 * hashCode + this.second.hashCode();
+- return 31 * hashCode + this.direction.hashCode();
++ int i = this.first.hashCode();
++
++ i = 31 * i + this.second.hashCode();
++ i = 31 * i + this.direction.hashCode();
++ return i;
+ }
+ }
+ }