941 lines
36 KiB
Java
941 lines
36 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import net.minecraft.world.item.DyeColor;
|
|
import com.google.common.cache.CacheLoader;
|
|
import com.google.common.cache.CacheBuilder;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import net.minecraft.world.item.TooltipFlag;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.level.material.Fluids;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import net.minecraft.core.NonNullList;
|
|
import net.minecraft.world.item.CreativeModeTab;
|
|
import net.minecraft.world.level.material.PushReaction;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.network.chat.TranslatableComponent;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.stats.Stat;
|
|
import net.minecraft.stats.Stats;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.level.Explosion;
|
|
import net.minecraft.world.entity.ExperienceOrb;
|
|
import net.minecraft.world.entity.item.ItemEntity;
|
|
import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.storage.loot.LootTable;
|
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|
import java.util.Collections;
|
|
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
|
import net.minecraft.world.level.storage.loot.LootContext;
|
|
import net.minecraft.core.Registry;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.MenuProvider;
|
|
import net.minecraft.network.protocol.game.DebugPackets;
|
|
import java.util.Random;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.world.level.LevelReader;
|
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
|
import net.minecraft.world.level.material.Fluid;
|
|
import net.minecraft.world.item.BlockPlaceContext;
|
|
import net.minecraft.tags.FluidTags;
|
|
import net.minecraft.world.level.pathfinder.PathComputationType;
|
|
import net.minecraft.tags.BlockTags;
|
|
import net.minecraft.tags.Tag;
|
|
import net.minecraft.core.Vec3i;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.stream.Stream;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.phys.shapes.Shapes;
|
|
import net.minecraft.world.phys.shapes.BooleanOp;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.item.BlockItem;
|
|
import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap;
|
|
import net.minecraft.world.item.Item;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.world.level.block.state.StateDefinition;
|
|
import net.minecraft.world.level.material.MaterialColor;
|
|
import net.minecraft.world.level.material.Material;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
import com.google.common.cache.LoadingCache;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.core.IdMapper;
|
|
import org.apache.logging.log4j.Logger;
|
|
import net.minecraft.world.level.ItemLike;
|
|
|
|
public class Block implements ItemLike {
|
|
protected static final Logger LOGGER;
|
|
public static final IdMapper<BlockState> BLOCK_STATE_REGISTRY;
|
|
private static final Direction[] UPDATE_SHAPE_ORDER;
|
|
private static final LoadingCache<VoxelShape, Boolean> SHAPE_FULL_BLOCK_CACHE;
|
|
private static final VoxelShape RIGID_SUPPORT_SHAPE;
|
|
private static final VoxelShape CENTER_SUPPORT_SHAPE;
|
|
protected final int lightEmission;
|
|
protected final float destroySpeed;
|
|
protected final float explosionResistance;
|
|
protected final boolean isTicking;
|
|
protected final SoundType soundType;
|
|
protected final Material material;
|
|
protected final MaterialColor materialColor;
|
|
private final float friction;
|
|
private final float speedFactor;
|
|
private final float jumpFactor;
|
|
protected final StateDefinition<Block, BlockState> stateDefinition;
|
|
private BlockState defaultBlockState;
|
|
protected final boolean hasCollision;
|
|
private final boolean dynamicShape;
|
|
private final boolean canOcclude;
|
|
@Nullable
|
|
private ResourceLocation drops;
|
|
@Nullable
|
|
private String descriptionId;
|
|
@Nullable
|
|
private Item item;
|
|
private static final ThreadLocal<Object2ByteLinkedOpenHashMap<BlockStatePairKey>> OCCLUSION_CACHE;
|
|
|
|
public static int getId(@Nullable final BlockState byg) {
|
|
if (byg == null) {
|
|
return 0;
|
|
}
|
|
final int integer2 = Block.BLOCK_STATE_REGISTRY.getId(byg);
|
|
return (integer2 == -1) ? 0 : integer2;
|
|
}
|
|
|
|
public static BlockState stateById(final int integer) {
|
|
final BlockState byg2 = Block.BLOCK_STATE_REGISTRY.byId(integer);
|
|
return (byg2 == null) ? Blocks.AIR.defaultBlockState() : byg2;
|
|
}
|
|
|
|
public static Block byItem(@Nullable final Item bef) {
|
|
if (bef instanceof BlockItem) {
|
|
return ((BlockItem)bef).getBlock();
|
|
}
|
|
return Blocks.AIR;
|
|
}
|
|
|
|
public static BlockState pushEntitiesUp(final BlockState byg1, final BlockState byg2, final Level bjt, final BlockPos fk) {
|
|
final VoxelShape cwc5 = Shapes.joinUnoptimized(byg1.getCollisionShape(bjt, fk), byg2.getCollisionShape(bjt, fk), BooleanOp.ONLY_SECOND).move(fk.getX(), fk.getY(), fk.getZ());
|
|
final List<Entity> list6 = bjt.getEntities(null, cwc5.bounds());
|
|
for (final Entity akn8 : list6) {
|
|
final double double9 = Shapes.collide(Direction.Axis.Y, akn8.getBoundingBox().move(0.0, 1.0, 0.0), Stream.<VoxelShape>of(cwc5), -1.0);
|
|
akn8.teleportTo(akn8.getX(), akn8.getY() + 1.0 + double9, akn8.getZ());
|
|
}
|
|
return byg2;
|
|
}
|
|
|
|
public static VoxelShape box(final double double1, final double double2, final double double3, final double double4, final double double5, final double double6) {
|
|
return Shapes.box(double1 / 16.0, double2 / 16.0, double3 / 16.0, double4 / 16.0, double5 / 16.0, double6 / 16.0);
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isValidSpawn(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final EntityType<?> akr) {
|
|
return byg.isFaceSturdy(bjd, fk, Direction.UP) && this.lightEmission < 14;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isAir(final BlockState byg) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public int getLightEmission(final BlockState byg) {
|
|
return this.lightEmission;
|
|
}
|
|
|
|
@Deprecated
|
|
public Material getMaterial(final BlockState byg) {
|
|
return this.material;
|
|
}
|
|
|
|
@Deprecated
|
|
public MaterialColor getMapColor(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return this.materialColor;
|
|
}
|
|
|
|
@Deprecated
|
|
public void updateNeighbourShapes(final BlockState byg, final LevelAccessor bju, final BlockPos fk, final int integer) {
|
|
try (final BlockPos.PooledMutableBlockPos b6 = BlockPos.PooledMutableBlockPos.acquire()) {
|
|
for (final Direction fp11 : Block.UPDATE_SHAPE_ORDER) {
|
|
b6.set((Vec3i)fk).move(fp11);
|
|
final BlockState byg2 = bju.getBlockState(b6);
|
|
final BlockState byg3 = byg2.updateShape(fp11.getOpposite(), byg, bju, b6, fk);
|
|
updateOrDestroy(byg2, byg3, bju, b6, integer);
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean is(final Tag<Block> aaz) {
|
|
return aaz.contains(this);
|
|
}
|
|
|
|
public static BlockState updateFromNeighbourShapes(final BlockState byg, final LevelAccessor bju, final BlockPos fk) {
|
|
BlockState byg2 = byg;
|
|
final BlockPos.MutableBlockPos a5 = new BlockPos.MutableBlockPos();
|
|
for (final Direction fp9 : Block.UPDATE_SHAPE_ORDER) {
|
|
a5.set(fk).move(fp9);
|
|
byg2 = byg2.updateShape(fp9, bju.getBlockState(a5), bju, fk, a5);
|
|
}
|
|
return byg2;
|
|
}
|
|
|
|
public static void updateOrDestroy(final BlockState byg1, final BlockState byg2, final LevelAccessor bju, final BlockPos fk, final int integer) {
|
|
if (byg2 != byg1) {
|
|
if (byg2.isAir()) {
|
|
if (!bju.isClientSide()) {
|
|
bju.destroyBlock(fk, (integer & 0x20) == 0x0);
|
|
}
|
|
}
|
|
else {
|
|
bju.setBlock(fk, byg2, integer & 0xFFFFFFDF);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public void updateIndirectNeighbourShapes(final BlockState byg, final LevelAccessor bju, final BlockPos fk, final int integer) {
|
|
}
|
|
|
|
@Deprecated
|
|
public BlockState updateShape(final BlockState byg1, final Direction fp, final BlockState byg3, final LevelAccessor bju, final BlockPos fk5, final BlockPos fk6) {
|
|
return byg1;
|
|
}
|
|
|
|
@Deprecated
|
|
public BlockState rotate(final BlockState byg, final Rotation btr) {
|
|
return byg;
|
|
}
|
|
|
|
@Deprecated
|
|
public BlockState mirror(final BlockState byg, final Mirror bsr) {
|
|
return byg;
|
|
}
|
|
|
|
public Block(final Properties c) {
|
|
final StateDefinition.Builder<Block, BlockState> a3 = new StateDefinition.Builder<Block, BlockState>(this);
|
|
this.createBlockStateDefinition(a3);
|
|
this.material = c.material;
|
|
this.materialColor = c.materialColor;
|
|
this.hasCollision = c.hasCollision;
|
|
this.soundType = c.soundType;
|
|
this.lightEmission = c.lightEmission;
|
|
this.explosionResistance = c.explosionResistance;
|
|
this.destroySpeed = c.destroyTime;
|
|
this.isTicking = c.isTicking;
|
|
this.friction = c.friction;
|
|
this.speedFactor = c.speedFactor;
|
|
this.jumpFactor = c.jumpFactor;
|
|
this.dynamicShape = c.dynamicShape;
|
|
this.drops = c.drops;
|
|
this.canOcclude = c.canOcclude;
|
|
this.stateDefinition = a3.<BlockState>create(BlockState::new);
|
|
this.registerDefaultState(this.stateDefinition.any());
|
|
}
|
|
|
|
public static boolean isExceptionForConnection(final Block bpe) {
|
|
return bpe instanceof LeavesBlock || bpe == Blocks.BARRIER || bpe == Blocks.CARVED_PUMPKIN || bpe == Blocks.JACK_O_LANTERN || bpe == Blocks.MELON || bpe == Blocks.PUMPKIN || bpe.is(BlockTags.SHULKER_BOXES);
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isRedstoneConductor(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return byg.getMaterial().isSolidBlocking() && byg.isCollisionShapeFullBlock(bjd, fk) && !byg.isSignalSource();
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isSuffocating(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return this.material.blocksMotion() && byg.isCollisionShapeFullBlock(bjd, fk);
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isViewBlocking(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return byg.isSuffocating(bjd, fk);
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isPathfindable(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final PathComputationType cqo) {
|
|
switch (cqo) {
|
|
case LAND: {
|
|
return !byg.isCollisionShapeFullBlock(bjd, fk);
|
|
}
|
|
case WATER: {
|
|
return bjd.getFluidState(fk).is(FluidTags.WATER);
|
|
}
|
|
case AIR: {
|
|
return !byg.isCollisionShapeFullBlock(bjd, fk);
|
|
}
|
|
default: {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public RenderShape getRenderShape(final BlockState byg) {
|
|
return RenderShape.MODEL;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean canBeReplaced(final BlockState byg, final BlockPlaceContext bcn) {
|
|
return this.material.isReplaceable() && (bcn.getItemInHand().isEmpty() || bcn.getItemInHand().getItem() != this.asItem());
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean canBeReplaced(final BlockState byg, final Fluid cof) {
|
|
return this.material.isReplaceable() || !this.material.isSolid();
|
|
}
|
|
|
|
@Deprecated
|
|
public float getDestroySpeed(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return this.destroySpeed;
|
|
}
|
|
|
|
public boolean isRandomlyTicking(final BlockState byg) {
|
|
return this.isTicking;
|
|
}
|
|
|
|
public boolean isEntityBlock() {
|
|
return this instanceof EntityBlock;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean hasPostProcess(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean emissiveRendering(final BlockState byg) {
|
|
return false;
|
|
}
|
|
|
|
public static boolean shouldRenderFace(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
|
|
final BlockPos fk2 = fk.relative(fp);
|
|
final BlockState byg2 = bjd.getBlockState(fk2);
|
|
if (byg.skipRendering(byg2, fp)) {
|
|
return false;
|
|
}
|
|
if (!byg2.canOcclude()) {
|
|
return true;
|
|
}
|
|
final BlockStatePairKey a7 = new BlockStatePairKey(byg, byg2, fp);
|
|
final Object2ByteLinkedOpenHashMap<BlockStatePairKey> object2ByteLinkedOpenHashMap8 = Block.OCCLUSION_CACHE.get();
|
|
final byte byte9 = object2ByteLinkedOpenHashMap8.getAndMoveToFirst(a7);
|
|
if (byte9 != 127) {
|
|
return byte9 != 0;
|
|
}
|
|
final VoxelShape cwc10 = byg.getFaceOcclusionShape(bjd, fk, fp);
|
|
final VoxelShape cwc11 = byg2.getFaceOcclusionShape(bjd, fk2, fp.getOpposite());
|
|
final boolean boolean12 = Shapes.joinIsNotEmpty(cwc10, cwc11, BooleanOp.ONLY_FIRST);
|
|
if (object2ByteLinkedOpenHashMap8.size() == 2048) {
|
|
object2ByteLinkedOpenHashMap8.removeLastByte();
|
|
}
|
|
object2ByteLinkedOpenHashMap8.putAndMoveToFirst(a7, (byte)(byte)(boolean12 ? 1 : 0));
|
|
return boolean12;
|
|
}
|
|
|
|
@Deprecated
|
|
public final boolean canOcclude(final BlockState byg) {
|
|
return this.canOcclude;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean skipRendering(final BlockState byg1, final BlockState byg2, final Direction fp) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public VoxelShape getShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
|
|
return Shapes.block();
|
|
}
|
|
|
|
@Deprecated
|
|
public VoxelShape getCollisionShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
|
|
return this.hasCollision ? byg.getShape(bjd, fk) : Shapes.empty();
|
|
}
|
|
|
|
@Deprecated
|
|
public VoxelShape getOcclusionShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return byg.getShape(bjd, fk);
|
|
}
|
|
|
|
@Deprecated
|
|
public VoxelShape getInteractionShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return Shapes.empty();
|
|
}
|
|
|
|
public static boolean canSupportRigidBlock(final BlockGetter bjd, final BlockPos fk) {
|
|
final BlockState byg3 = bjd.getBlockState(fk);
|
|
return !byg3.is(BlockTags.LEAVES) && !Shapes.joinIsNotEmpty(byg3.getCollisionShape(bjd, fk).getFaceShape(Direction.UP), Block.RIGID_SUPPORT_SHAPE, BooleanOp.ONLY_SECOND);
|
|
}
|
|
|
|
public static boolean canSupportCenter(final LevelReader bjw, final BlockPos fk, final Direction fp) {
|
|
final BlockState byg4 = bjw.getBlockState(fk);
|
|
return !byg4.is(BlockTags.LEAVES) && !Shapes.joinIsNotEmpty(byg4.getCollisionShape(bjw, fk).getFaceShape(fp), Block.CENTER_SUPPORT_SHAPE, BooleanOp.ONLY_SECOND);
|
|
}
|
|
|
|
public static boolean isFaceSturdy(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
|
|
return !byg.is(BlockTags.LEAVES) && isFaceFull(byg.getCollisionShape(bjd, fk), fp);
|
|
}
|
|
|
|
public static boolean isFaceFull(final VoxelShape cwc, final Direction fp) {
|
|
final VoxelShape cwc2 = cwc.getFaceShape(fp);
|
|
return isShapeFullBlock(cwc2);
|
|
}
|
|
|
|
public static boolean isShapeFullBlock(final VoxelShape cwc) {
|
|
return Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(cwc);
|
|
}
|
|
|
|
@Deprecated
|
|
public final boolean isSolidRender(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return byg.canOcclude() && isShapeFullBlock(byg.getOcclusionShape(bjd, fk));
|
|
}
|
|
|
|
public boolean propagatesSkylightDown(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return !isShapeFullBlock(byg.getShape(bjd, fk)) && byg.getFluidState().isEmpty();
|
|
}
|
|
|
|
@Deprecated
|
|
public int getLightBlock(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
if (byg.isSolidRender(bjd, fk)) {
|
|
return bjd.getMaxLightLevel();
|
|
}
|
|
return byg.propagatesSkylightDown(bjd, fk) ? 0 : 1;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean useShapeForLightOcclusion(final BlockState byg) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public void randomTick(final BlockState byg, final ServerLevel xd, final BlockPos fk, final Random random) {
|
|
this.tick(byg, xd, fk, random);
|
|
}
|
|
|
|
@Deprecated
|
|
public void tick(final BlockState byg, final ServerLevel xd, final BlockPos fk, final Random random) {
|
|
}
|
|
|
|
public void animateTick(final BlockState byg, final Level bjt, final BlockPos fk, final Random random) {
|
|
}
|
|
|
|
public void destroy(final LevelAccessor bju, final BlockPos fk, final BlockState byg) {
|
|
}
|
|
|
|
@Deprecated
|
|
public void neighborChanged(final BlockState byg, final Level bjt, final BlockPos fk3, final Block bpe, final BlockPos fk5, final boolean boolean6) {
|
|
DebugPackets.sendNeighborsUpdatePacket(bjt, fk3);
|
|
}
|
|
|
|
public int getTickDelay(final LevelReader bjw) {
|
|
return 10;
|
|
}
|
|
|
|
@Nullable
|
|
@Deprecated
|
|
public MenuProvider getMenuProvider(final BlockState byg, final Level bjt, final BlockPos fk) {
|
|
return null;
|
|
}
|
|
|
|
@Deprecated
|
|
public void onPlace(final BlockState byg1, final Level bjt, final BlockPos fk, final BlockState byg4, final boolean boolean5) {
|
|
}
|
|
|
|
@Deprecated
|
|
public void onRemove(final BlockState byg1, final Level bjt, final BlockPos fk, final BlockState byg4, final boolean boolean5) {
|
|
if (this.isEntityBlock() && byg1.getBlock() != byg4.getBlock()) {
|
|
bjt.removeBlockEntity(fk);
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public float getDestroyProgress(final BlockState byg, final Player ayg, final BlockGetter bjd, final BlockPos fk) {
|
|
final float float6 = byg.getDestroySpeed(bjd, fk);
|
|
if (float6 == -1.0f) {
|
|
return 0.0f;
|
|
}
|
|
final int integer7 = ayg.canDestroy(byg) ? 30 : 100;
|
|
return ayg.getDestroySpeed(byg) / float6 / integer7;
|
|
}
|
|
|
|
@Deprecated
|
|
public void spawnAfterBreak(final BlockState byg, final Level bjt, final BlockPos fk, final ItemStack bek) {
|
|
}
|
|
|
|
public ResourceLocation getLootTable() {
|
|
if (this.drops == null) {
|
|
final ResourceLocation sm2 = Registry.BLOCK.getKey(this);
|
|
this.drops = new ResourceLocation(sm2.getNamespace(), "blocks/" + sm2.getPath());
|
|
}
|
|
return this.drops;
|
|
}
|
|
|
|
@Deprecated
|
|
public List<ItemStack> getDrops(final BlockState byg, final LootContext.Builder a) {
|
|
final ResourceLocation sm4 = this.getLootTable();
|
|
if (sm4 == BuiltInLootTables.EMPTY) {
|
|
return Collections.<ItemStack>emptyList();
|
|
}
|
|
final LootContext cru5 = a.<BlockState>withParameter(LootContextParams.BLOCK_STATE, byg).create(LootContextParamSets.BLOCK);
|
|
final ServerLevel xd6 = cru5.getLevel();
|
|
final LootTable crx7 = xd6.getServer().getLootTables().get(sm4);
|
|
return crx7.getRandomItems(cru5);
|
|
}
|
|
|
|
public static List<ItemStack> getDrops(final BlockState byg, final ServerLevel xd, final BlockPos fk, @Nullable final BlockEntity bwi) {
|
|
final LootContext.Builder a5 = new LootContext.Builder(xd).withRandom(xd.random).<BlockPos>withParameter(LootContextParams.BLOCK_POS, fk).<ItemStack>withParameter(LootContextParams.TOOL, ItemStack.EMPTY).<BlockEntity>withOptionalParameter(LootContextParams.BLOCK_ENTITY, bwi);
|
|
return byg.getDrops(a5);
|
|
}
|
|
|
|
public static List<ItemStack> getDrops(final BlockState byg, final ServerLevel xd, final BlockPos fk, @Nullable final BlockEntity bwi, @Nullable final Entity akn, final ItemStack bek) {
|
|
final LootContext.Builder a7 = new LootContext.Builder(xd).withRandom(xd.random).<BlockPos>withParameter(LootContextParams.BLOCK_POS, fk).<ItemStack>withParameter(LootContextParams.TOOL, bek).<Entity>withOptionalParameter(LootContextParams.THIS_ENTITY, akn).<BlockEntity>withOptionalParameter(LootContextParams.BLOCK_ENTITY, bwi);
|
|
return byg.getDrops(a7);
|
|
}
|
|
|
|
public static void dropResources(final BlockState byg, final Level bjt, final BlockPos fk) {
|
|
if (bjt instanceof ServerLevel) {
|
|
getDrops(byg, (ServerLevel)bjt, fk, null).forEach(bek -> popResource(bjt, fk, bek));
|
|
}
|
|
byg.spawnAfterBreak(bjt, fk, ItemStack.EMPTY);
|
|
}
|
|
|
|
public static void dropResources(final BlockState byg, final Level bjt, final BlockPos fk, @Nullable final BlockEntity bwi) {
|
|
if (bjt instanceof ServerLevel) {
|
|
getDrops(byg, (ServerLevel)bjt, fk, bwi).forEach(bek -> popResource(bjt, fk, bek));
|
|
}
|
|
byg.spawnAfterBreak(bjt, fk, ItemStack.EMPTY);
|
|
}
|
|
|
|
public static void dropResources(final BlockState byg, final Level bjt, final BlockPos fk, @Nullable final BlockEntity bwi, final Entity akn, final ItemStack bek) {
|
|
if (bjt instanceof ServerLevel) {
|
|
getDrops(byg, (ServerLevel)bjt, fk, bwi, akn, bek).forEach(bek -> popResource(bjt, fk, bek));
|
|
}
|
|
byg.spawnAfterBreak(bjt, fk, bek);
|
|
}
|
|
|
|
public static void popResource(final Level bjt, final BlockPos fk, final ItemStack bek) {
|
|
if (bjt.isClientSide || bek.isEmpty() || !bjt.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
|
return;
|
|
}
|
|
final float float4 = 0.5f;
|
|
final double double5 = bjt.random.nextFloat() * 0.5f + 0.25;
|
|
final double double6 = bjt.random.nextFloat() * 0.5f + 0.25;
|
|
final double double7 = bjt.random.nextFloat() * 0.5f + 0.25;
|
|
final ItemEntity avy11 = new ItemEntity(bjt, fk.getX() + double5, fk.getY() + double6, fk.getZ() + double7, bek);
|
|
avy11.setDefaultPickUpDelay();
|
|
bjt.addFreshEntity(avy11);
|
|
}
|
|
|
|
protected void popExperience(final Level bjt, final BlockPos fk, int integer) {
|
|
if (!bjt.isClientSide && bjt.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
|
while (integer > 0) {
|
|
final int integer2 = ExperienceOrb.getExperienceValue(integer);
|
|
integer -= integer2;
|
|
bjt.addFreshEntity(new ExperienceOrb(bjt, fk.getX() + 0.5, fk.getY() + 0.5, fk.getZ() + 0.5, integer2));
|
|
}
|
|
}
|
|
}
|
|
|
|
public float getExplosionResistance() {
|
|
return this.explosionResistance;
|
|
}
|
|
|
|
public void wasExploded(final Level bjt, final BlockPos fk, final Explosion bjm) {
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean canSurvive(final BlockState byg, final LevelReader bjw, final BlockPos fk) {
|
|
return true;
|
|
}
|
|
|
|
@Deprecated
|
|
public InteractionResult use(final BlockState byg, final Level bjt, final BlockPos fk, final Player ayg, final InteractionHand ajh, final BlockHitResult cvd) {
|
|
return InteractionResult.PASS;
|
|
}
|
|
|
|
public void stepOn(final Level bjt, final BlockPos fk, final Entity akn) {
|
|
}
|
|
|
|
@Nullable
|
|
public BlockState getStateForPlacement(final BlockPlaceContext bcn) {
|
|
return this.defaultBlockState();
|
|
}
|
|
|
|
@Deprecated
|
|
public void attack(final BlockState byg, final Level bjt, final BlockPos fk, final Player ayg) {
|
|
}
|
|
|
|
@Deprecated
|
|
public int getSignal(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
|
|
return 0;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isSignalSource(final BlockState byg) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public void entityInside(final BlockState byg, final Level bjt, final BlockPos fk, final Entity akn) {
|
|
}
|
|
|
|
@Deprecated
|
|
public int getDirectSignal(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
|
|
return 0;
|
|
}
|
|
|
|
public void playerDestroy(final Level bjt, final Player ayg, final BlockPos fk, final BlockState byg, @Nullable final BlockEntity bwi, final ItemStack bek) {
|
|
ayg.awardStat(Stats.BLOCK_MINED.get(this));
|
|
ayg.causeFoodExhaustion(0.005f);
|
|
dropResources(byg, bjt, fk, bwi, ayg, bek);
|
|
}
|
|
|
|
public void setPlacedBy(final Level bjt, final BlockPos fk, final BlockState byg, @Nullable final LivingEntity akw, final ItemStack bek) {
|
|
}
|
|
|
|
public boolean isPossibleToRespawnInThis() {
|
|
return !this.material.isSolid() && !this.material.isLiquid();
|
|
}
|
|
|
|
public Component getName() {
|
|
return new TranslatableComponent(this.getDescriptionId(), new Object[0]);
|
|
}
|
|
|
|
public String getDescriptionId() {
|
|
if (this.descriptionId == null) {
|
|
this.descriptionId = Util.makeDescriptionId("block", Registry.BLOCK.getKey(this));
|
|
}
|
|
return this.descriptionId;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean triggerEvent(final BlockState byg, final Level bjt, final BlockPos fk, final int integer4, final int integer5) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public PushReaction getPistonPushReaction(final BlockState byg) {
|
|
return this.material.getPushReaction();
|
|
}
|
|
|
|
@Deprecated
|
|
public float getShadeBrightness(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
return byg.isCollisionShapeFullBlock(bjd, fk) ? 0.2f : 1.0f;
|
|
}
|
|
|
|
public void fallOn(final Level bjt, final BlockPos fk, final Entity akn, final float float4) {
|
|
akn.causeFallDamage(float4, 1.0f);
|
|
}
|
|
|
|
public void updateEntityAfterFallOn(final BlockGetter bjd, final Entity akn) {
|
|
akn.setDeltaMovement(akn.getDeltaMovement().multiply(1.0, 0.0, 1.0));
|
|
}
|
|
|
|
public ItemStack getCloneItemStack(final BlockGetter bjd, final BlockPos fk, final BlockState byg) {
|
|
return new ItemStack(this);
|
|
}
|
|
|
|
public void fillItemCategory(final CreativeModeTab bda, final NonNullList<ItemStack> fy) {
|
|
fy.add(new ItemStack(this));
|
|
}
|
|
|
|
@Deprecated
|
|
public FluidState getFluidState(final BlockState byg) {
|
|
return Fluids.EMPTY.defaultFluidState();
|
|
}
|
|
|
|
public float getFriction() {
|
|
return this.friction;
|
|
}
|
|
|
|
public float getSpeedFactor() {
|
|
return this.speedFactor;
|
|
}
|
|
|
|
public float getJumpFactor() {
|
|
return this.jumpFactor;
|
|
}
|
|
|
|
@Deprecated
|
|
public long getSeed(final BlockState byg, final BlockPos fk) {
|
|
return Mth.getSeed(fk);
|
|
}
|
|
|
|
public void onProjectileHit(final Level bjt, final BlockState byg, final BlockHitResult cvd, final Entity akn) {
|
|
}
|
|
|
|
public void playerWillDestroy(final Level bjt, final BlockPos fk, final BlockState byg, final Player ayg) {
|
|
bjt.levelEvent(ayg, 2001, fk, getId(byg));
|
|
}
|
|
|
|
public void handleRain(final Level bjt, final BlockPos fk) {
|
|
}
|
|
|
|
public boolean dropFromExplosion(final Explosion bjm) {
|
|
return true;
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean hasAnalogOutputSignal(final BlockState byg) {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
public int getAnalogOutputSignal(final BlockState byg, final Level bjt, final BlockPos fk) {
|
|
return 0;
|
|
}
|
|
|
|
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
|
|
}
|
|
|
|
public StateDefinition<Block, BlockState> getStateDefinition() {
|
|
return this.stateDefinition;
|
|
}
|
|
|
|
protected final void registerDefaultState(final BlockState byg) {
|
|
this.defaultBlockState = byg;
|
|
}
|
|
|
|
public final BlockState defaultBlockState() {
|
|
return this.defaultBlockState;
|
|
}
|
|
|
|
public OffsetType getOffsetType() {
|
|
return OffsetType.NONE;
|
|
}
|
|
|
|
@Deprecated
|
|
public Vec3 getOffset(final BlockState byg, final BlockGetter bjd, final BlockPos fk) {
|
|
final OffsetType b5 = this.getOffsetType();
|
|
if (b5 == OffsetType.NONE) {
|
|
return Vec3.ZERO;
|
|
}
|
|
final long long6 = Mth.getSeed(fk.getX(), 0, fk.getZ());
|
|
return new Vec3(((long6 & 0xFL) / 15.0f - 0.5) * 0.5, (b5 == OffsetType.XYZ) ? (((long6 >> 4 & 0xFL) / 15.0f - 1.0) * 0.2) : 0.0, ((long6 >> 8 & 0xFL) / 15.0f - 0.5) * 0.5);
|
|
}
|
|
|
|
public SoundType getSoundType(final BlockState byg) {
|
|
return this.soundType;
|
|
}
|
|
|
|
@Override
|
|
public Item asItem() {
|
|
if (this.item == null) {
|
|
this.item = Item.byBlock(this);
|
|
}
|
|
return this.item;
|
|
}
|
|
|
|
public boolean hasDynamicShape() {
|
|
return this.dynamicShape;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "Block{" + Registry.BLOCK.getKey(this) + "}";
|
|
}
|
|
|
|
public void appendHoverText(final ItemStack bek, @Nullable final BlockGetter bjd, final List<Component> list, final TooltipFlag bft) {
|
|
}
|
|
|
|
static {
|
|
LOGGER = LogManager.getLogger();
|
|
BLOCK_STATE_REGISTRY = new IdMapper<BlockState>();
|
|
UPDATE_SHAPE_ORDER = new Direction[] { Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH, Direction.DOWN, Direction.UP };
|
|
SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().<VoxelShape, Boolean>build(new CacheLoader<VoxelShape, Boolean>() {
|
|
@Override
|
|
public Boolean load(final VoxelShape cwc) {
|
|
return !Shapes.joinIsNotEmpty(Shapes.block(), cwc, BooleanOp.NOT_SAME);
|
|
}
|
|
});
|
|
RIGID_SUPPORT_SHAPE = Shapes.join(Shapes.block(), box(2.0, 0.0, 2.0, 14.0, 16.0, 14.0), BooleanOp.ONLY_FIRST);
|
|
CENTER_SUPPORT_SHAPE = box(7.0, 0.0, 7.0, 9.0, 10.0, 9.0);
|
|
final Object2ByteLinkedOpenHashMap<BlockStatePairKey> object2ByteLinkedOpenHashMap1;
|
|
OCCLUSION_CACHE = ThreadLocal.<Object2ByteLinkedOpenHashMap<BlockStatePairKey>>withInitial(() -> {
|
|
object2ByteLinkedOpenHashMap1 = new Object2ByteLinkedOpenHashMap<BlockStatePairKey>(2048, 0.25f) {
|
|
protected void rehash(final int integer) {
|
|
}
|
|
};
|
|
object2ByteLinkedOpenHashMap1.defaultReturnValue((byte)127);
|
|
return object2ByteLinkedOpenHashMap1;
|
|
});
|
|
}
|
|
|
|
public static final class BlockStatePairKey {
|
|
private final BlockState first;
|
|
private final BlockState second;
|
|
private final Direction direction;
|
|
|
|
public BlockStatePairKey(final BlockState byg1, final BlockState byg2, final Direction fp) {
|
|
this.first = byg1;
|
|
this.second = byg2;
|
|
this.direction = fp;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(final Object object) {
|
|
if (this == object) {
|
|
return true;
|
|
}
|
|
if (!(object instanceof BlockStatePairKey)) {
|
|
return false;
|
|
}
|
|
final BlockStatePairKey a3 = (BlockStatePairKey)object;
|
|
return this.first == a3.first && this.second == a3.second && this.direction == a3.direction;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int integer2 = this.first.hashCode();
|
|
integer2 = 31 * integer2 + this.second.hashCode();
|
|
integer2 = 31 * integer2 + this.direction.hashCode();
|
|
return integer2;
|
|
}
|
|
}
|
|
|
|
public static class Properties {
|
|
private Material material;
|
|
private MaterialColor materialColor;
|
|
private boolean hasCollision;
|
|
private SoundType soundType;
|
|
private int lightEmission;
|
|
private float explosionResistance;
|
|
private float destroyTime;
|
|
private boolean isTicking;
|
|
private float friction;
|
|
private float speedFactor;
|
|
private float jumpFactor;
|
|
private ResourceLocation drops;
|
|
private boolean canOcclude;
|
|
private boolean dynamicShape;
|
|
|
|
private Properties(final Material cok, final MaterialColor col) {
|
|
this.hasCollision = true;
|
|
this.soundType = SoundType.STONE;
|
|
this.friction = 0.6f;
|
|
this.speedFactor = 1.0f;
|
|
this.jumpFactor = 1.0f;
|
|
this.canOcclude = true;
|
|
this.material = cok;
|
|
this.materialColor = col;
|
|
}
|
|
|
|
public static Properties of(final Material cok) {
|
|
return of(cok, cok.getColor());
|
|
}
|
|
|
|
public static Properties of(final Material cok, final DyeColor bdg) {
|
|
return of(cok, bdg.getMaterialColor());
|
|
}
|
|
|
|
public static Properties of(final Material cok, final MaterialColor col) {
|
|
return new Properties(cok, col);
|
|
}
|
|
|
|
public static Properties copy(final Block bpe) {
|
|
final Properties c2 = new Properties(bpe.material, bpe.materialColor);
|
|
c2.material = bpe.material;
|
|
c2.destroyTime = bpe.destroySpeed;
|
|
c2.explosionResistance = bpe.explosionResistance;
|
|
c2.hasCollision = bpe.hasCollision;
|
|
c2.isTicking = bpe.isTicking;
|
|
c2.lightEmission = bpe.lightEmission;
|
|
c2.materialColor = bpe.materialColor;
|
|
c2.soundType = bpe.soundType;
|
|
c2.friction = bpe.getFriction();
|
|
c2.speedFactor = bpe.getSpeedFactor();
|
|
c2.dynamicShape = bpe.dynamicShape;
|
|
c2.canOcclude = bpe.canOcclude;
|
|
return c2;
|
|
}
|
|
|
|
public Properties noCollission() {
|
|
this.hasCollision = false;
|
|
this.canOcclude = false;
|
|
return this;
|
|
}
|
|
|
|
public Properties noOcclusion() {
|
|
this.canOcclude = false;
|
|
return this;
|
|
}
|
|
|
|
public Properties friction(final float float1) {
|
|
this.friction = float1;
|
|
return this;
|
|
}
|
|
|
|
public Properties speedFactor(final float float1) {
|
|
this.speedFactor = float1;
|
|
return this;
|
|
}
|
|
|
|
public Properties jumpFactor(final float float1) {
|
|
this.jumpFactor = float1;
|
|
return this;
|
|
}
|
|
|
|
protected Properties sound(final SoundType buj) {
|
|
this.soundType = buj;
|
|
return this;
|
|
}
|
|
|
|
protected Properties lightLevel(final int integer) {
|
|
this.lightEmission = integer;
|
|
return this;
|
|
}
|
|
|
|
public Properties strength(final float float1, final float float2) {
|
|
this.destroyTime = float1;
|
|
this.explosionResistance = Math.max(0.0f, float2);
|
|
return this;
|
|
}
|
|
|
|
protected Properties instabreak() {
|
|
return this.strength(0.0f);
|
|
}
|
|
|
|
protected Properties strength(final float float1) {
|
|
this.strength(float1, float1);
|
|
return this;
|
|
}
|
|
|
|
protected Properties randomTicks() {
|
|
this.isTicking = true;
|
|
return this;
|
|
}
|
|
|
|
protected Properties dynamicShape() {
|
|
this.dynamicShape = true;
|
|
return this;
|
|
}
|
|
|
|
protected Properties noDrops() {
|
|
this.drops = BuiltInLootTables.EMPTY;
|
|
return this;
|
|
}
|
|
|
|
public Properties dropsLike(final Block bpe) {
|
|
this.drops = bpe.getLootTable();
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public enum OffsetType {
|
|
NONE,
|
|
XZ,
|
|
XYZ;
|
|
}
|
|
}
|