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

273 lines
14 KiB
Java

package net.minecraft.world.level.block;
import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.util.Mth;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.BlockPlaceContext;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
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.DoubleBlockHalf;
import net.minecraft.world.level.block.state.properties.DoorHingeSide;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
public class DoorBlock extends Block {
public static final DirectionProperty FACING;
public static final BooleanProperty OPEN;
public static final EnumProperty<DoorHingeSide> HINGE;
public static final BooleanProperty POWERED;
public static final EnumProperty<DoubleBlockHalf> HALF;
protected static final VoxelShape SOUTH_AABB;
protected static final VoxelShape NORTH_AABB;
protected static final VoxelShape WEST_AABB;
protected static final VoxelShape EAST_AABB;
protected DoorBlock(final Properties c) {
super(c);
this.registerDefaultState(((((((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)DoorBlock.FACING, Direction.NORTH)).setValue((Property<Comparable>)DoorBlock.OPEN, false)).setValue(DoorBlock.HINGE, DoorHingeSide.LEFT)).setValue((Property<Comparable>)DoorBlock.POWERED, false)).<DoubleBlockHalf, DoubleBlockHalf>setValue(DoorBlock.HALF, DoubleBlockHalf.LOWER));
}
@Override
public VoxelShape getShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
final Direction fp6 = byg.<Direction>getValue((Property<Direction>)DoorBlock.FACING);
final boolean boolean7 = !byg.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN);
final boolean boolean8 = byg.<DoorHingeSide>getValue(DoorBlock.HINGE) == DoorHingeSide.RIGHT;
switch (fp6) {
default: {
return boolean7 ? DoorBlock.EAST_AABB : (boolean8 ? DoorBlock.NORTH_AABB : DoorBlock.SOUTH_AABB);
}
case SOUTH: {
return boolean7 ? DoorBlock.SOUTH_AABB : (boolean8 ? DoorBlock.EAST_AABB : DoorBlock.WEST_AABB);
}
case WEST: {
return boolean7 ? DoorBlock.WEST_AABB : (boolean8 ? DoorBlock.SOUTH_AABB : DoorBlock.NORTH_AABB);
}
case NORTH: {
return boolean7 ? DoorBlock.NORTH_AABB : (boolean8 ? DoorBlock.WEST_AABB : DoorBlock.EAST_AABB);
}
}
}
@Override
public BlockState updateShape(final BlockState byg1, final Direction fp, final BlockState byg3, final LevelAccessor bju, final BlockPos fk5, final BlockPos fk6) {
final DoubleBlockHalf bzd8 = byg1.<DoubleBlockHalf>getValue(DoorBlock.HALF);
if (fp.getAxis() == Direction.Axis.Y && bzd8 == DoubleBlockHalf.LOWER == (fp == Direction.UP)) {
if (byg3.getBlock() == this && byg3.<DoubleBlockHalf>getValue(DoorBlock.HALF) != bzd8) {
return (((((AbstractStateHolder<O, BlockState>)byg1).setValue((Property<Comparable>)DoorBlock.FACING, (Comparable)byg3.<V>getValue((Property<V>)DoorBlock.FACING))).setValue((Property<Comparable>)DoorBlock.OPEN, (Comparable)byg3.<V>getValue((Property<V>)DoorBlock.OPEN))).setValue(DoorBlock.HINGE, (Comparable)byg3.<V>getValue((Property<V>)DoorBlock.HINGE))).<Comparable, Comparable>setValue((Property<Comparable>)DoorBlock.POWERED, (Comparable)byg3.<V>getValue((Property<V>)DoorBlock.POWERED));
}
return Blocks.AIR.defaultBlockState();
}
else {
if (bzd8 == DoubleBlockHalf.LOWER && fp == Direction.DOWN && !byg1.canSurvive(bju, fk5)) {
return Blocks.AIR.defaultBlockState();
}
return super.updateShape(byg1, fp, byg3, bju, fk5, fk6);
}
}
@Override
public void playerDestroy(final Level bjt, final Player ayg, final BlockPos fk, final BlockState byg, @Nullable final BlockEntity bwi, final ItemStack bek) {
super.playerDestroy(bjt, ayg, fk, Blocks.AIR.defaultBlockState(), bwi, bek);
}
@Override
public void playerWillDestroy(final Level bjt, final BlockPos fk, final BlockState byg, final Player ayg) {
final DoubleBlockHalf bzd6 = byg.<DoubleBlockHalf>getValue(DoorBlock.HALF);
final BlockPos fk2 = (bzd6 == DoubleBlockHalf.LOWER) ? fk.above() : fk.below();
final BlockState byg2 = bjt.getBlockState(fk2);
if (byg2.getBlock() == this && byg2.<DoubleBlockHalf>getValue(DoorBlock.HALF) != bzd6) {
bjt.setBlock(fk2, Blocks.AIR.defaultBlockState(), 35);
bjt.levelEvent(ayg, 2001, fk2, Block.getId(byg2));
final ItemStack bek9 = ayg.getMainHandItem();
if (!bjt.isClientSide && !ayg.isCreative() && ayg.canDestroy(byg2)) {
Block.dropResources(byg, bjt, fk, null, ayg, bek9);
Block.dropResources(byg2, bjt, fk2, null, ayg, bek9);
}
}
super.playerWillDestroy(bjt, fk, byg, ayg);
}
@Override
public boolean isPathfindable(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final PathComputationType cqo) {
switch (cqo) {
case LAND: {
return byg.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN);
}
case WATER: {
return false;
}
case AIR: {
return byg.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN);
}
default: {
return false;
}
}
}
private int getCloseSound() {
return (this.material == Material.METAL) ? 1011 : 1012;
}
private int getOpenSound() {
return (this.material == Material.METAL) ? 1005 : 1006;
}
@Nullable
@Override
public BlockState getStateForPlacement(final BlockPlaceContext bcn) {
final BlockPos fk3 = bcn.getClickedPos();
if (fk3.getY() < 255 && bcn.getLevel().getBlockState(fk3.above()).canBeReplaced(bcn)) {
final Level bjt4 = bcn.getLevel();
final boolean boolean5 = bjt4.hasNeighborSignal(fk3) || bjt4.hasNeighborSignal(fk3.above());
return ((((((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).setValue((Property<Comparable>)DoorBlock.FACING, bcn.getHorizontalDirection())).setValue(DoorBlock.HINGE, this.getHinge(bcn))).setValue((Property<Comparable>)DoorBlock.POWERED, boolean5)).setValue((Property<Comparable>)DoorBlock.OPEN, boolean5)).<DoubleBlockHalf, DoubleBlockHalf>setValue(DoorBlock.HALF, DoubleBlockHalf.LOWER);
}
return null;
}
@Override
public void setPlacedBy(final Level bjt, final BlockPos fk, final BlockState byg, final LivingEntity akw, final ItemStack bek) {
bjt.setBlock(fk.above(), ((AbstractStateHolder<O, BlockState>)byg).<DoubleBlockHalf, DoubleBlockHalf>setValue(DoorBlock.HALF, DoubleBlockHalf.UPPER), 3);
}
private DoorHingeSide getHinge(final BlockPlaceContext bcn) {
final BlockGetter bjd3 = bcn.getLevel();
final BlockPos fk4 = bcn.getClickedPos();
final Direction fp5 = bcn.getHorizontalDirection();
final BlockPos fk5 = fk4.above();
final Direction fp6 = fp5.getCounterClockWise();
final BlockPos fk6 = fk4.relative(fp6);
final BlockState byg9 = bjd3.getBlockState(fk6);
final BlockPos fk7 = fk5.relative(fp6);
final BlockState byg10 = bjd3.getBlockState(fk7);
final Direction fp7 = fp5.getClockWise();
final BlockPos fk8 = fk4.relative(fp7);
final BlockState byg11 = bjd3.getBlockState(fk8);
final BlockPos fk9 = fk5.relative(fp7);
final BlockState byg12 = bjd3.getBlockState(fk9);
final int integer17 = (byg9.isCollisionShapeFullBlock(bjd3, fk6) ? -1 : 0) + (byg10.isCollisionShapeFullBlock(bjd3, fk7) ? -1 : 0) + (byg11.isCollisionShapeFullBlock(bjd3, fk8) ? 1 : 0) + (byg12.isCollisionShapeFullBlock(bjd3, fk9) ? 1 : 0);
final boolean boolean18 = byg9.getBlock() == this && byg9.<DoubleBlockHalf>getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
final boolean boolean19 = byg11.getBlock() == this && byg11.<DoubleBlockHalf>getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
if ((boolean18 && !boolean19) || integer17 > 0) {
return DoorHingeSide.RIGHT;
}
if ((boolean19 && !boolean18) || integer17 < 0) {
return DoorHingeSide.LEFT;
}
final int integer18 = fp5.getStepX();
final int integer19 = fp5.getStepZ();
final Vec3 cvi22 = bcn.getClickLocation();
final double double23 = cvi22.x - fk4.getX();
final double double24 = cvi22.z - fk4.getZ();
return ((integer18 < 0 && double24 < 0.5) || (integer18 > 0 && double24 > 0.5) || (integer19 < 0 && double23 > 0.5) || (integer19 > 0 && double23 < 0.5)) ? DoorHingeSide.RIGHT : DoorHingeSide.LEFT;
}
@Override
public InteractionResult use(BlockState byg, final Level bjt, final BlockPos fk, final Player ayg, final InteractionHand ajh, final BlockHitResult cvd) {
if (this.material == Material.METAL) {
return InteractionResult.PASS;
}
byg = ((AbstractStateHolder<O, BlockState>)byg).<Comparable>cycle((Property<Comparable>)DoorBlock.OPEN);
bjt.setBlock(fk, byg, 10);
bjt.levelEvent(ayg, ((boolean)byg.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN)) ? this.getOpenSound() : this.getCloseSound(), fk, 0);
return InteractionResult.SUCCESS;
}
public void setOpen(final Level bjt, final BlockPos fk, final boolean boolean3) {
final BlockState byg5 = bjt.getBlockState(fk);
if (byg5.getBlock() != this || byg5.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN) == boolean3) {
return;
}
bjt.setBlock(fk, ((AbstractStateHolder<O, BlockState>)byg5).<Comparable, Boolean>setValue((Property<Comparable>)DoorBlock.OPEN, boolean3), 10);
this.playSound(bjt, fk, boolean3);
}
@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) || bjt.hasNeighborSignal(fk3.relative((byg.<DoubleBlockHalf>getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER) ? Direction.UP : Direction.DOWN));
if (bpe != this && boolean7 != byg.<Boolean>getValue((Property<Boolean>)DoorBlock.POWERED)) {
if (boolean7 != byg.<Boolean>getValue((Property<Boolean>)DoorBlock.OPEN)) {
this.playSound(bjt, fk3, boolean7);
}
bjt.setBlock(fk3, (((AbstractStateHolder<O, BlockState>)byg).setValue((Property<Comparable>)DoorBlock.POWERED, boolean7)).<Comparable, Boolean>setValue((Property<Comparable>)DoorBlock.OPEN, boolean7), 2);
}
}
@Override
public boolean canSurvive(final BlockState byg, final LevelReader bjw, final BlockPos fk) {
final BlockPos fk2 = fk.below();
final BlockState byg2 = bjw.getBlockState(fk2);
if (byg.<DoubleBlockHalf>getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER) {
return byg2.isFaceSturdy(bjw, fk2, Direction.UP);
}
return byg2.getBlock() == this;
}
private void playSound(final Level bjt, final BlockPos fk, final boolean boolean3) {
bjt.levelEvent(null, boolean3 ? this.getOpenSound() : this.getCloseSound(), fk, 0);
}
@Override
public PushReaction getPistonPushReaction(final BlockState byg) {
return PushReaction.DESTROY;
}
@Override
public BlockState rotate(final BlockState byg, final Rotation btr) {
return ((AbstractStateHolder<O, BlockState>)byg).<Comparable, Direction>setValue((Property<Comparable>)DoorBlock.FACING, btr.rotate(byg.<Direction>getValue((Property<Direction>)DoorBlock.FACING)));
}
@Override
public BlockState mirror(final BlockState byg, final Mirror bsr) {
if (bsr == Mirror.NONE) {
return byg;
}
return ((AbstractStateHolder<O, BlockState>)byg.rotate(bsr.getRotation(byg.<Direction>getValue((Property<Direction>)DoorBlock.FACING)))).<DoorHingeSide>cycle(DoorBlock.HINGE);
}
@Override
public long getSeed(final BlockState byg, final BlockPos fk) {
return Mth.getSeed(fk.getX(), fk.below((int)((byg.<DoubleBlockHalf>getValue(DoorBlock.HALF) != DoubleBlockHalf.LOWER) ? 1 : 0)).getY(), fk.getZ());
}
@Override
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
a.add(DoorBlock.HALF, DoorBlock.FACING, DoorBlock.OPEN, DoorBlock.HINGE, DoorBlock.POWERED);
}
static {
FACING = HorizontalDirectionalBlock.FACING;
OPEN = BlockStateProperties.OPEN;
HINGE = BlockStateProperties.DOOR_HINGE;
POWERED = BlockStateProperties.POWERED;
HALF = BlockStateProperties.DOUBLE_BLOCK_HALF;
SOUTH_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 16.0, 3.0);
NORTH_AABB = Block.box(0.0, 0.0, 13.0, 16.0, 16.0, 16.0);
WEST_AABB = Block.box(13.0, 0.0, 0.0, 16.0, 16.0, 16.0);
EAST_AABB = Block.box(0.0, 0.0, 0.0, 3.0, 16.0, 16.0);
}
}