package com.atsuishio.superbwarfare.block; import com.atsuishio.superbwarfare.block.entity.ContainerBlockEntity; import com.atsuishio.superbwarfare.entity.vehicle.ICannonEntity; import com.atsuishio.superbwarfare.init.ModBlockEntities; import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModSounds; import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.*; 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.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.BooleanProperty; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import javax.annotation.Nullable; import java.util.List; @SuppressWarnings("deprecation") public class ContainerBlock extends BaseEntityBlock { public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; public static final BooleanProperty OPENED = BooleanProperty.create("opened"); public ContainerBlock() { super(BlockBehaviour.Properties.of().sound(SoundType.METAL).strength(3.0f).noOcclusion().requiresCorrectToolForDrops()); this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(OPENED, false)); } @Override public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) { if (!pLevel.isClientSide) { ItemStack stack = pPlayer.getItemInHand(pHand); if (stack.is(ModItems.CROWBAR.get())) { BlockEntity blockEntity = pLevel.getBlockEntity(pPos); if (!(blockEntity instanceof ContainerBlockEntity containerBlockEntity)) return InteractionResult.PASS; if (!hasEntity(pLevel, pPos)) { pPlayer.displayClientMessage(Component.translatable("des.superbwarfare.container.fail.empty"), true); return InteractionResult.PASS; } if (canOpen(pLevel, pPos, containerBlockEntity.entityType, containerBlockEntity.entity)) { pLevel.setBlockAndUpdate(pPos, pState.setValue(OPENED, true)); if (!pLevel.isClientSide()) { pLevel.playSound(null, BlockPos.containing(pPos.getX(), pPos.getY(), pPos.getZ()), ModSounds.OPEN.get(), SoundSource.BLOCKS, 1, 1); } else { pLevel.playLocalSound(pPos.getX(), pPos.getY(), pPos.getZ(), ModSounds.OPEN.get(), SoundSource.BLOCKS, 1, 1, false); } return InteractionResult.SUCCESS; } else { pPlayer.displayClientMessage(Component.translatable("des.superbwarfare.container.fail.open"), true); } } else { pPlayer.displayClientMessage(Component.translatable("des.superbwarfare.container.fail.crowbar"), true); } } return InteractionResult.PASS; } public boolean hasEntity(Level pLevel, BlockPos pPos) { BlockEntity blockEntity = pLevel.getBlockEntity(pPos); if (!(blockEntity instanceof ContainerBlockEntity containerBlockEntity)) return false; return containerBlockEntity.entity != null || containerBlockEntity.entityType != null; } public boolean canOpen(Level pLevel, BlockPos pPos, EntityType entityType, Entity entity) { boolean flag = true; int w = 0; int h = 0; boolean extra = entityType == ModEntities.MLE_1934.get() || entityType == ModEntities.MK_42.get() || entity instanceof ICannonEntity; if (entityType != null) { w = (int) (entityType.getDimensions().width / 2 + (extra ? 2 : 0)); h = (int) (entityType.getDimensions().height + (extra ? 2 : 0)); } if (entity != null) { w = (int) (entity.getType().getDimensions().width / 2 + (extra ? 2 : 0)); h = (int) (entity.getType().getDimensions().height + (extra ? 2 : 0)); } for (int i = -w; i < w + 1; i++) { for (int j = 0; j < h; j++) { for (int k = -w; k < w + 1; k++) { if (i == 0 && j == 0 && k == 0) { continue; } //TODO 修改开箱 if (!pLevel.getBlockState(pPos.offset(i, j, k)).isAir()) { flag = false; } } } } return flag; } @Nullable @Override public BlockEntityTicker getTicker(Level pLevel, BlockState pState, BlockEntityType pBlockEntityType) { if (!pLevel.isClientSide) { return createTickerHelper(pBlockEntityType, ModBlockEntities.CONTAINER.get(), ContainerBlockEntity::serverTick); } return null; } @Override public void appendHoverText(ItemStack pStack, @Nullable BlockGetter pLevel, List pTooltip, TooltipFlag pFlag) { super.appendHoverText(pStack, pLevel, pTooltip, pFlag); CompoundTag compoundtag = BlockItem.getBlockEntityData(pStack); if (compoundtag != null) { if (compoundtag.contains("EntityType")) { String s = getTranslationKey(compoundtag.getString("EntityType")); pTooltip.add(Component.translatable(s == null ? "des.superbwarfare.container.empty" : s).withStyle(ChatFormatting.GRAY)); } } } @Nullable public String getTranslationKey(String path) { String[] parts = path.split(":"); if (parts.length > 1) { return "entity." + parts[0] + "." + parts[1]; } else { return null; } } @Override public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return state.getValue(OPENED) ? box(1, 0, 1, 15, 14, 15) : box(0, 0, 0, 16, 15, 16); } @Override public RenderShape getRenderShape(BlockState state) { return RenderShape.ENTITYBLOCK_ANIMATED; } @Nullable @Override public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { return new ContainerBlockEntity(blockPos, blockState); } @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(FACING).add(OPENED); } @Override public BlockState getStateForPlacement(BlockPlaceContext context) { return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()).setValue(OPENED, false); } @Override public ItemStack getCloneItemStack(BlockGetter pLevel, BlockPos pPos, BlockState pState) { ItemStack itemstack = super.getCloneItemStack(pLevel, pPos, pState); pLevel.getBlockEntity(pPos, ModBlockEntities.CONTAINER.get()).ifPresent((blockEntity) -> blockEntity.saveToItem(itemstack)); return itemstack; } }