minecraft-source/src/net/minecraft/world/level/block/BellBlock.java

287 lines
14 KiB
Java

package net.minecraft.world.level.block;
import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.item.BlockPlaceContext;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.level.block.entity.BellBlockEntity;
import net.minecraft.stats.Stats;
import javax.annotation.Nullable;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.BellAttachType;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
public class BellBlock extends BaseEntityBlock {
public static final DirectionProperty FACING;
private static final EnumProperty<BellAttachType> ATTACHMENT;
public static final BooleanProperty POWERED;
private static final VoxelShape NORTH_SOUTH_FLOOR_SHAPE;
private static final VoxelShape EAST_WEST_FLOOR_SHAPE;
private static final VoxelShape BELL_TOP_SHAPE;
private static final VoxelShape BELL_BOTTOM_SHAPE;
private static final VoxelShape BELL_SHAPE;
private static final VoxelShape NORTH_SOUTH_BETWEEN;
private static final VoxelShape EAST_WEST_BETWEEN;
private static final VoxelShape TO_WEST;
private static final VoxelShape TO_EAST;
private static final VoxelShape TO_NORTH;
private static final VoxelShape TO_SOUTH;
private static final VoxelShape CEILING_SHAPE;
public BellBlock(final Properties c) {
super(c);
this.registerDefaultState(((((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)BellBlock.FACING, Direction.NORTH)).setValue(BellBlock.ATTACHMENT, BellAttachType.FLOOR)).<Comparable, Boolean>setValue((Property<Comparable>)BellBlock.POWERED, false));
}
@Override
public void neighborChanged(final BlockState byg, final Level bjt, final BlockPos fk3, final Block bpe, final BlockPos fk5, final boolean boolean6) {
final boolean boolean7 = bjt.hasNeighborSignal(fk3);
if (boolean7 != byg.<Boolean>getValue((Property<Boolean>)BellBlock.POWERED)) {
if (boolean7) {
this.attemptToRing(bjt, fk3, null);
}
bjt.setBlock(fk3, ((AbstractStateHolder<O, BlockState>)byg).<Comparable, Boolean>setValue((Property<Comparable>)BellBlock.POWERED, boolean7), 3);
}
}
@Override
public void onProjectileHit(final Level bjt, final BlockState byg, final BlockHitResult cvd, final Entity akn) {
if (akn instanceof AbstractArrow) {
final Entity akn2 = ((AbstractArrow)akn).getOwner();
final Player ayg7 = (akn2 instanceof Player) ? ((Player)akn2) : null;
this.onHit(bjt, byg, cvd, ayg7, true);
}
}
@Override
public InteractionResult use(final BlockState byg, final Level bjt, final BlockPos fk, final Player ayg, final InteractionHand ajh, final BlockHitResult cvd) {
return this.onHit(bjt, byg, cvd, ayg, true) ? InteractionResult.SUCCESS : InteractionResult.PASS;
}
public boolean onHit(final Level bjt, final BlockState byg, final BlockHitResult cvd, @Nullable final Player ayg, final boolean boolean5) {
final Direction fp7 = cvd.getDirection();
final BlockPos fk8 = cvd.getBlockPos();
final boolean boolean6 = !boolean5 || this.isProperHit(byg, fp7, cvd.getLocation().y - fk8.getY());
if (boolean6) {
final boolean boolean7 = this.attemptToRing(bjt, fk8, fp7);
if (boolean7 && ayg != null) {
ayg.awardStat(Stats.BELL_RING);
}
return true;
}
return false;
}
private boolean isProperHit(final BlockState byg, final Direction fp, final double double3) {
if (fp.getAxis() == Direction.Axis.Y || double3 > 0.8123999834060669) {
return false;
}
final Direction fp2 = byg.<Direction>getValue((Property<Direction>)BellBlock.FACING);
final BellAttachType byw7 = byg.<BellAttachType>getValue(BellBlock.ATTACHMENT);
switch (byw7) {
case FLOOR: {
return fp2.getAxis() == fp.getAxis();
}
case SINGLE_WALL:
case DOUBLE_WALL: {
return fp2.getAxis() != fp.getAxis();
}
case CEILING: {
return true;
}
default: {
return false;
}
}
}
public boolean attemptToRing(final Level bjt, final BlockPos fk, @Nullable Direction fp) {
final BlockEntity bwi5 = bjt.getBlockEntity(fk);
if (!bjt.isClientSide && bwi5 instanceof BellBlockEntity) {
if (fp == null) {
fp = bjt.getBlockState(fk).<Direction>getValue((Property<Direction>)BellBlock.FACING);
}
((BellBlockEntity)bwi5).onHit(fp);
bjt.playSound(null, fk, SoundEvents.BELL_BLOCK, SoundSource.BLOCKS, 2.0f, 1.0f);
return true;
}
return false;
}
private VoxelShape getVoxelShape(final BlockState byg) {
final Direction fp3 = byg.<Direction>getValue((Property<Direction>)BellBlock.FACING);
final BellAttachType byw4 = byg.<BellAttachType>getValue(BellBlock.ATTACHMENT);
if (byw4 == BellAttachType.FLOOR) {
if (fp3 == Direction.NORTH || fp3 == Direction.SOUTH) {
return BellBlock.NORTH_SOUTH_FLOOR_SHAPE;
}
return BellBlock.EAST_WEST_FLOOR_SHAPE;
}
else {
if (byw4 == BellAttachType.CEILING) {
return BellBlock.CEILING_SHAPE;
}
if (byw4 == BellAttachType.DOUBLE_WALL) {
if (fp3 == Direction.NORTH || fp3 == Direction.SOUTH) {
return BellBlock.NORTH_SOUTH_BETWEEN;
}
return BellBlock.EAST_WEST_BETWEEN;
}
else {
if (fp3 == Direction.NORTH) {
return BellBlock.TO_NORTH;
}
if (fp3 == Direction.SOUTH) {
return BellBlock.TO_SOUTH;
}
if (fp3 == Direction.EAST) {
return BellBlock.TO_EAST;
}
return BellBlock.TO_WEST;
}
}
}
@Override
public VoxelShape getCollisionShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
return this.getVoxelShape(byg);
}
@Override
public VoxelShape getShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
return this.getVoxelShape(byg);
}
@Override
public RenderShape getRenderShape(final BlockState byg) {
return RenderShape.MODEL;
}
@Nullable
@Override
public BlockState getStateForPlacement(final BlockPlaceContext bcn) {
final Direction fp4 = bcn.getClickedFace();
final BlockPos fk5 = bcn.getClickedPos();
final Level bjt6 = bcn.getLevel();
final Direction.Axis a7 = fp4.getAxis();
if (a7 == Direction.Axis.Y) {
final BlockState byg3 = (((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).setValue(BellBlock.ATTACHMENT, (fp4 == Direction.DOWN) ? BellAttachType.CEILING : BellAttachType.FLOOR)).<Comparable, Direction>setValue((Property<Comparable>)BellBlock.FACING, bcn.getHorizontalDirection());
if (byg3.canSurvive(bcn.getLevel(), fk5)) {
return byg3;
}
}
else {
final boolean boolean8 = (a7 == Direction.Axis.X && bjt6.getBlockState(fk5.west()).isFaceSturdy(bjt6, fk5.west(), Direction.EAST) && bjt6.getBlockState(fk5.east()).isFaceSturdy(bjt6, fk5.east(), Direction.WEST)) || (a7 == Direction.Axis.Z && bjt6.getBlockState(fk5.north()).isFaceSturdy(bjt6, fk5.north(), Direction.SOUTH) && bjt6.getBlockState(fk5.south()).isFaceSturdy(bjt6, fk5.south(), Direction.NORTH));
BlockState byg3 = (((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).setValue((Property<Comparable>)BellBlock.FACING, fp4.getOpposite())).<BellAttachType, BellAttachType>setValue(BellBlock.ATTACHMENT, boolean8 ? BellAttachType.DOUBLE_WALL : BellAttachType.SINGLE_WALL);
if (byg3.canSurvive(bcn.getLevel(), bcn.getClickedPos())) {
return byg3;
}
final boolean boolean9 = bjt6.getBlockState(fk5.below()).isFaceSturdy(bjt6, fk5.below(), Direction.UP);
byg3 = ((AbstractStateHolder<O, BlockState>)byg3).<BellAttachType, BellAttachType>setValue(BellBlock.ATTACHMENT, boolean9 ? BellAttachType.FLOOR : BellAttachType.CEILING);
if (byg3.canSurvive(bcn.getLevel(), bcn.getClickedPos())) {
return byg3;
}
}
return null;
}
@Override
public BlockState updateShape(final BlockState byg1, final Direction fp, final BlockState byg3, final LevelAccessor bju, final BlockPos fk5, final BlockPos fk6) {
final BellAttachType byw8 = byg1.<BellAttachType>getValue(BellBlock.ATTACHMENT);
final Direction fp2 = getConnectedDirection(byg1).getOpposite();
if (fp2 == fp && !byg1.canSurvive(bju, fk5) && byw8 != BellAttachType.DOUBLE_WALL) {
return Blocks.AIR.defaultBlockState();
}
if (fp.getAxis() == byg1.<Direction>getValue((Property<Direction>)BellBlock.FACING).getAxis()) {
if (byw8 == BellAttachType.DOUBLE_WALL && !byg3.isFaceSturdy(bju, fk6, fp)) {
return (((AbstractStateHolder<O, BlockState>)byg1).setValue(BellBlock.ATTACHMENT, BellAttachType.SINGLE_WALL)).<Comparable, Direction>setValue((Property<Comparable>)BellBlock.FACING, fp.getOpposite());
}
if (byw8 == BellAttachType.SINGLE_WALL && fp2.getOpposite() == fp && byg3.isFaceSturdy(bju, fk6, byg1.<Direction>getValue((Property<Direction>)BellBlock.FACING))) {
return ((AbstractStateHolder<O, BlockState>)byg1).<BellAttachType, BellAttachType>setValue(BellBlock.ATTACHMENT, BellAttachType.DOUBLE_WALL);
}
}
return super.updateShape(byg1, fp, byg3, bju, fk5, fk6);
}
@Override
public boolean canSurvive(final BlockState byg, final LevelReader bjw, final BlockPos fk) {
return FaceAttachedHorizontalDirectionalBlock.canAttach(bjw, fk, getConnectedDirection(byg).getOpposite());
}
private static Direction getConnectedDirection(final BlockState byg) {
switch (byg.<BellAttachType>getValue(BellBlock.ATTACHMENT)) {
case CEILING: {
return Direction.DOWN;
}
case FLOOR: {
return Direction.UP;
}
default: {
return byg.<Direction>getValue((Property<Direction>)BellBlock.FACING).getOpposite();
}
}
}
@Override
public PushReaction getPistonPushReaction(final BlockState byg) {
return PushReaction.DESTROY;
}
@Override
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
a.add(BellBlock.FACING, BellBlock.ATTACHMENT, BellBlock.POWERED);
}
@Nullable
@Override
public BlockEntity newBlockEntity(final BlockGetter bjd) {
return new BellBlockEntity();
}
@Override
public boolean isPathfindable(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final PathComputationType cqo) {
return false;
}
static {
FACING = HorizontalDirectionalBlock.FACING;
ATTACHMENT = BlockStateProperties.BELL_ATTACHMENT;
POWERED = BlockStateProperties.POWERED;
NORTH_SOUTH_FLOOR_SHAPE = Block.box(0.0, 0.0, 4.0, 16.0, 16.0, 12.0);
EAST_WEST_FLOOR_SHAPE = Block.box(4.0, 0.0, 0.0, 12.0, 16.0, 16.0);
BELL_TOP_SHAPE = Block.box(5.0, 6.0, 5.0, 11.0, 13.0, 11.0);
BELL_BOTTOM_SHAPE = Block.box(4.0, 4.0, 4.0, 12.0, 6.0, 12.0);
BELL_SHAPE = Shapes.or(BellBlock.BELL_BOTTOM_SHAPE, BellBlock.BELL_TOP_SHAPE);
NORTH_SOUTH_BETWEEN = Shapes.or(BellBlock.BELL_SHAPE, Block.box(7.0, 13.0, 0.0, 9.0, 15.0, 16.0));
EAST_WEST_BETWEEN = Shapes.or(BellBlock.BELL_SHAPE, Block.box(0.0, 13.0, 7.0, 16.0, 15.0, 9.0));
TO_WEST = Shapes.or(BellBlock.BELL_SHAPE, Block.box(0.0, 13.0, 7.0, 13.0, 15.0, 9.0));
TO_EAST = Shapes.or(BellBlock.BELL_SHAPE, Block.box(3.0, 13.0, 7.0, 16.0, 15.0, 9.0));
TO_NORTH = Shapes.or(BellBlock.BELL_SHAPE, Block.box(7.0, 13.0, 0.0, 9.0, 15.0, 13.0));
TO_SOUTH = Shapes.or(BellBlock.BELL_SHAPE, Block.box(7.0, 13.0, 3.0, 9.0, 15.0, 16.0));
CEILING_SHAPE = Shapes.or(BellBlock.BELL_SHAPE, Block.box(7.0, 13.0, 7.0, 9.0, 16.0, 9.0));
}
}