287 lines
14 KiB
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));
|
|
}
|
|
}
|