Code/net/minecraft/world/level/block/EnderChestBlock.java

177 lines
7.8 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.level.block;
import com.mojang.serialization.MapCodec;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.stats.Stats;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.monster.piglin.PiglinAi;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.inventory.PlayerEnderChestContainer;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.ScheduledTickAccess;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> implements SimpleWaterloggedBlock {
public static final MapCodec<EnderChestBlock> CODEC = simpleCodec(EnderChestBlock::new);
public static final EnumProperty<Direction> FACING = HorizontalDirectionalBlock.FACING;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final VoxelShape SHAPE = Block.column(14.0, 0.0, 14.0);
private static final Component CONTAINER_TITLE = Component.translatable("container.enderchest");
@Override
public MapCodec<EnderChestBlock> codec() {
return CODEC;
}
protected EnderChestBlock(BlockBehaviour.Properties p_53121_) {
super(p_53121_, () -> BlockEntityType.ENDER_CHEST);
this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(WATERLOGGED, false));
}
@Override
public DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> combine(
BlockState p_53149_, Level p_53150_, BlockPos p_53151_, boolean p_53152_
) {
return DoubleBlockCombiner.Combiner::acceptNone;
}
@Override
protected VoxelShape getShape(BlockState p_53171_, BlockGetter p_53172_, BlockPos p_53173_, CollisionContext p_53174_) {
return SHAPE;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext p_53128_) {
FluidState fluidstate = p_53128_.getLevel().getFluidState(p_53128_.getClickedPos());
return this.defaultBlockState().setValue(FACING, p_53128_.getHorizontalDirection().getOpposite()).setValue(WATERLOGGED, fluidstate.getType() == Fluids.WATER);
}
@Override
protected InteractionResult useWithoutItem(BlockState p_53137_, Level p_53138_, BlockPos p_53139_, Player p_53140_, BlockHitResult p_53142_) {
PlayerEnderChestContainer playerenderchestcontainer = p_53140_.getEnderChestInventory();
if (playerenderchestcontainer != null && p_53138_.getBlockEntity(p_53139_) instanceof EnderChestBlockEntity enderchestblockentity) {
BlockPos $$9 = p_53139_.above();
if (p_53138_.getBlockState($$9).isRedstoneConductor(p_53138_, $$9)) {
return InteractionResult.SUCCESS;
} else {
if (p_53138_ instanceof ServerLevel serverlevel) {
playerenderchestcontainer.setActiveChest(enderchestblockentity);
p_53140_.openMenu(
new SimpleMenuProvider((p_53124_, p_53125_, p_53126_) -> ChestMenu.threeRows(p_53124_, p_53125_, playerenderchestcontainer), CONTAINER_TITLE)
);
p_53140_.awardStat(Stats.OPEN_ENDERCHEST);
PiglinAi.angerNearbyPiglins(serverlevel, p_53140_, true);
}
return InteractionResult.SUCCESS;
}
} else {
return InteractionResult.SUCCESS;
}
}
@Override
public BlockEntity newBlockEntity(BlockPos p_153208_, BlockState p_153209_) {
return new EnderChestBlockEntity(p_153208_, p_153209_);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153199_, BlockState p_153200_, BlockEntityType<T> p_153201_) {
return p_153199_.isClientSide ? createTickerHelper(p_153201_, BlockEntityType.ENDER_CHEST, EnderChestBlockEntity::lidAnimateTick) : null;
}
@Override
public void animateTick(BlockState p_221117_, Level p_221118_, BlockPos p_221119_, RandomSource p_221120_) {
for (int i = 0; i < 3; i++) {
int j = p_221120_.nextInt(2) * 2 - 1;
int k = p_221120_.nextInt(2) * 2 - 1;
double d0 = p_221119_.getX() + 0.5 + 0.25 * j;
double d1 = p_221119_.getY() + p_221120_.nextFloat();
double d2 = p_221119_.getZ() + 0.5 + 0.25 * k;
double d3 = p_221120_.nextFloat() * j;
double d4 = (p_221120_.nextFloat() - 0.5) * 0.125;
double d5 = p_221120_.nextFloat() * k;
p_221118_.addParticle(ParticleTypes.PORTAL, d0, d1, d2, d3, d4, d5);
}
}
@Override
protected BlockState rotate(BlockState p_53157_, Rotation p_53158_) {
return p_53157_.setValue(FACING, p_53158_.rotate(p_53157_.getValue(FACING)));
}
@Override
protected BlockState mirror(BlockState p_53154_, Mirror p_53155_) {
return p_53154_.rotate(p_53155_.getRotation(p_53154_.getValue(FACING)));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_53167_) {
p_53167_.add(FACING, WATERLOGGED);
}
@Override
protected FluidState getFluidState(BlockState p_53177_) {
return p_53177_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_53177_);
}
@Override
protected BlockState updateShape(
BlockState p_53160_,
LevelReader p_370015_,
ScheduledTickAccess p_361609_,
BlockPos p_53164_,
Direction p_53161_,
BlockPos p_53165_,
BlockState p_53162_,
RandomSource p_362906_
) {
if (p_53160_.getValue(WATERLOGGED)) {
p_361609_.scheduleTick(p_53164_, Fluids.WATER, Fluids.WATER.getTickDelay(p_370015_));
}
return super.updateShape(p_53160_, p_370015_, p_361609_, p_53164_, p_53161_, p_53165_, p_53162_, p_362906_);
}
@Override
protected boolean isPathfindable(BlockState p_53132_, PathComputationType p_53135_) {
return false;
}
@Override
protected void tick(BlockState p_221112_, ServerLevel p_221113_, BlockPos p_221114_, RandomSource p_221115_) {
BlockEntity blockentity = p_221113_.getBlockEntity(p_221114_);
if (blockentity instanceof EnderChestBlockEntity) {
((EnderChestBlockEntity)blockentity).recheckOpen();
}
}
}