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

443 lines
22 KiB
Java

package net.minecraft.world.level.block;
import net.minecraft.world.level.block.state.AbstractStateHolder;
import com.google.common.collect.Maps;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.DustParticleOptions;
import java.util.Random;
import net.minecraft.util.Mth;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.List;
import com.google.common.collect.Lists;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import java.util.Iterator;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.LevelAccessor;
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.state.properties.Property;
import net.minecraft.world.level.block.state.BlockState;
import com.google.common.collect.Sets;
import net.minecraft.core.BlockPos;
import java.util.Set;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.core.Direction;
import java.util.Map;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.RedstoneSide;
import net.minecraft.world.level.block.state.properties.EnumProperty;
public class RedStoneWireBlock extends Block {
public static final EnumProperty<RedstoneSide> NORTH;
public static final EnumProperty<RedstoneSide> EAST;
public static final EnumProperty<RedstoneSide> SOUTH;
public static final EnumProperty<RedstoneSide> WEST;
public static final IntegerProperty POWER;
public static final Map<Direction, EnumProperty<RedstoneSide>> PROPERTY_BY_DIRECTION;
protected static final VoxelShape[] SHAPE_BY_INDEX;
private boolean shouldSignal;
private final Set<BlockPos> toUpdate;
public RedStoneWireBlock(final Properties c) {
super(c);
this.shouldSignal = true;
this.toUpdate = Sets.newHashSet();
this.registerDefaultState(((((((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).setValue(RedStoneWireBlock.NORTH, RedstoneSide.NONE)).setValue(RedStoneWireBlock.EAST, RedstoneSide.NONE)).setValue(RedStoneWireBlock.SOUTH, RedstoneSide.NONE)).setValue(RedStoneWireBlock.WEST, RedstoneSide.NONE)).<Comparable, Integer>setValue((Property<Comparable>)RedStoneWireBlock.POWER, 0));
}
@Override
public VoxelShape getShape(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final CollisionContext cvn) {
return RedStoneWireBlock.SHAPE_BY_INDEX[getAABBIndex(byg)];
}
private static int getAABBIndex(final BlockState byg) {
int integer2 = 0;
final boolean boolean3 = byg.<RedstoneSide>getValue(RedStoneWireBlock.NORTH) != RedstoneSide.NONE;
final boolean boolean4 = byg.<RedstoneSide>getValue(RedStoneWireBlock.EAST) != RedstoneSide.NONE;
final boolean boolean5 = byg.<RedstoneSide>getValue(RedStoneWireBlock.SOUTH) != RedstoneSide.NONE;
final boolean boolean6 = byg.<RedstoneSide>getValue(RedStoneWireBlock.WEST) != RedstoneSide.NONE;
if (boolean3 || (boolean5 && !boolean3 && !boolean4 && !boolean6)) {
integer2 |= 1 << Direction.NORTH.get2DDataValue();
}
if (boolean4 || (boolean6 && !boolean3 && !boolean4 && !boolean5)) {
integer2 |= 1 << Direction.EAST.get2DDataValue();
}
if (boolean5 || (boolean3 && !boolean4 && !boolean5 && !boolean6)) {
integer2 |= 1 << Direction.SOUTH.get2DDataValue();
}
if (boolean6 || (boolean4 && !boolean3 && !boolean5 && !boolean6)) {
integer2 |= 1 << Direction.WEST.get2DDataValue();
}
return integer2;
}
@Override
public BlockState getStateForPlacement(final BlockPlaceContext bcn) {
final BlockGetter bjd3 = bcn.getLevel();
final BlockPos fk4 = bcn.getClickedPos();
return (((((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).setValue(RedStoneWireBlock.WEST, this.getConnectingSide(bjd3, fk4, Direction.WEST))).setValue(RedStoneWireBlock.EAST, this.getConnectingSide(bjd3, fk4, Direction.EAST))).setValue(RedStoneWireBlock.NORTH, this.getConnectingSide(bjd3, fk4, Direction.NORTH))).<RedstoneSide, RedstoneSide>setValue(RedStoneWireBlock.SOUTH, this.getConnectingSide(bjd3, fk4, Direction.SOUTH));
}
@Override
public BlockState updateShape(final BlockState byg1, final Direction fp, final BlockState byg3, final LevelAccessor bju, final BlockPos fk5, final BlockPos fk6) {
if (fp == Direction.DOWN) {
return byg1;
}
if (fp == Direction.UP) {
return (((((AbstractStateHolder<O, BlockState>)byg1).setValue(RedStoneWireBlock.WEST, this.getConnectingSide(bju, fk5, Direction.WEST))).setValue(RedStoneWireBlock.EAST, this.getConnectingSide(bju, fk5, Direction.EAST))).setValue(RedStoneWireBlock.NORTH, this.getConnectingSide(bju, fk5, Direction.NORTH))).<RedstoneSide, RedstoneSide>setValue(RedStoneWireBlock.SOUTH, this.getConnectingSide(bju, fk5, Direction.SOUTH));
}
return ((AbstractStateHolder<O, BlockState>)byg1).<RedstoneSide, RedstoneSide>setValue(RedStoneWireBlock.PROPERTY_BY_DIRECTION.get(fp), this.getConnectingSide(bju, fk5, fp));
}
@Override
public void updateIndirectNeighbourShapes(final BlockState byg, final LevelAccessor bju, final BlockPos fk, final int integer) {
try (final BlockPos.PooledMutableBlockPos b6 = BlockPos.PooledMutableBlockPos.acquire()) {
for (final Direction fp9 : Direction.Plane.HORIZONTAL) {
final RedstoneSide bzl10 = byg.<RedstoneSide>getValue(RedStoneWireBlock.PROPERTY_BY_DIRECTION.get(fp9));
if (bzl10 != RedstoneSide.NONE && bju.getBlockState(b6.set((Vec3i)fk).move(fp9)).getBlock() != this) {
b6.move(Direction.DOWN);
final BlockState byg2 = bju.getBlockState(b6);
if (byg2.getBlock() != Blocks.OBSERVER) {
final BlockPos fk2 = b6.relative(fp9.getOpposite());
final BlockState byg3 = byg2.updateShape(fp9.getOpposite(), bju.getBlockState(fk2), bju, b6, fk2);
Block.updateOrDestroy(byg2, byg3, bju, b6, integer);
}
b6.set((Vec3i)fk).move(fp9).move(Direction.UP);
final BlockState byg4 = bju.getBlockState(b6);
if (byg4.getBlock() == Blocks.OBSERVER) {
continue;
}
final BlockPos fk3 = b6.relative(fp9.getOpposite());
final BlockState byg5 = byg4.updateShape(fp9.getOpposite(), bju.getBlockState(fk3), bju, b6, fk3);
Block.updateOrDestroy(byg4, byg5, bju, b6, integer);
}
}
}
}
private RedstoneSide getConnectingSide(final BlockGetter bjd, final BlockPos fk, final Direction fp) {
final BlockPos fk2 = fk.relative(fp);
final BlockState byg6 = bjd.getBlockState(fk2);
final BlockPos fk3 = fk.above();
final BlockState byg7 = bjd.getBlockState(fk3);
if (!byg7.isRedstoneConductor(bjd, fk3)) {
final boolean boolean9 = byg6.isFaceSturdy(bjd, fk2, Direction.UP) || byg6.getBlock() == Blocks.HOPPER;
if (boolean9 && shouldConnectTo(bjd.getBlockState(fk2.above()))) {
if (byg6.isCollisionShapeFullBlock(bjd, fk2)) {
return RedstoneSide.UP;
}
return RedstoneSide.SIDE;
}
}
if (shouldConnectTo(byg6, fp) || (!byg6.isRedstoneConductor(bjd, fk2) && shouldConnectTo(bjd.getBlockState(fk2.below())))) {
return RedstoneSide.SIDE;
}
return RedstoneSide.NONE;
}
@Override
public boolean canSurvive(final BlockState byg, final LevelReader bjw, final BlockPos fk) {
final BlockPos fk2 = fk.below();
final BlockState byg2 = bjw.getBlockState(fk2);
return byg2.isFaceSturdy(bjw, fk2, Direction.UP) || byg2.getBlock() == Blocks.HOPPER;
}
private BlockState updatePowerStrength(final Level bjt, final BlockPos fk, BlockState byg) {
byg = this.updatePowerStrengthImpl(bjt, fk, byg);
final List<BlockPos> list5 = Lists.newArrayList(this.toUpdate);
this.toUpdate.clear();
for (final BlockPos fk2 : list5) {
bjt.updateNeighborsAt(fk2, this);
}
return byg;
}
private BlockState updatePowerStrengthImpl(final Level bjt, final BlockPos fk, BlockState byg) {
final BlockState byg2 = byg;
final int integer6 = byg2.<Integer>getValue((Property<Integer>)RedStoneWireBlock.POWER);
this.shouldSignal = false;
final int integer7 = bjt.getBestNeighborSignal(fk);
this.shouldSignal = true;
int integer8 = 0;
if (integer7 < 15) {
for (final Direction fp10 : Direction.Plane.HORIZONTAL) {
final BlockPos fk2 = fk.relative(fp10);
final BlockState byg3 = bjt.getBlockState(fk2);
integer8 = this.checkTarget(integer8, byg3);
final BlockPos fk3 = fk.above();
if (byg3.isRedstoneConductor(bjt, fk2) && !bjt.getBlockState(fk3).isRedstoneConductor(bjt, fk3)) {
integer8 = this.checkTarget(integer8, bjt.getBlockState(fk2.above()));
}
else {
if (byg3.isRedstoneConductor(bjt, fk2)) {
continue;
}
integer8 = this.checkTarget(integer8, bjt.getBlockState(fk2.below()));
}
}
}
int integer9 = integer8 - 1;
if (integer7 > integer9) {
integer9 = integer7;
}
if (integer6 != integer9) {
byg = ((AbstractStateHolder<O, BlockState>)byg).<Comparable, Integer>setValue((Property<Comparable>)RedStoneWireBlock.POWER, integer9);
if (bjt.getBlockState(fk) == byg2) {
bjt.setBlock(fk, byg, 2);
}
this.toUpdate.add(fk);
for (final Direction fp11 : Direction.values()) {
this.toUpdate.add(fk.relative(fp11));
}
}
return byg;
}
private void checkCornerChangeAt(final Level bjt, final BlockPos fk) {
if (bjt.getBlockState(fk).getBlock() != this) {
return;
}
bjt.updateNeighborsAt(fk, this);
for (final Direction fp7 : Direction.values()) {
bjt.updateNeighborsAt(fk.relative(fp7), this);
}
}
@Override
public void onPlace(final BlockState byg1, final Level bjt, final BlockPos fk, final BlockState byg4, final boolean boolean5) {
if (byg4.getBlock() == byg1.getBlock() || bjt.isClientSide) {
return;
}
this.updatePowerStrength(bjt, fk, byg1);
for (final Direction fp8 : Direction.Plane.VERTICAL) {
bjt.updateNeighborsAt(fk.relative(fp8), this);
}
for (final Direction fp8 : Direction.Plane.HORIZONTAL) {
this.checkCornerChangeAt(bjt, fk.relative(fp8));
}
for (final Direction fp8 : Direction.Plane.HORIZONTAL) {
final BlockPos fk2 = fk.relative(fp8);
if (bjt.getBlockState(fk2).isRedstoneConductor(bjt, fk2)) {
this.checkCornerChangeAt(bjt, fk2.above());
}
else {
this.checkCornerChangeAt(bjt, fk2.below());
}
}
}
@Override
public void onRemove(final BlockState byg1, final Level bjt, final BlockPos fk, final BlockState byg4, final boolean boolean5) {
if (boolean5 || byg1.getBlock() == byg4.getBlock()) {
return;
}
super.onRemove(byg1, bjt, fk, byg4, boolean5);
if (bjt.isClientSide) {
return;
}
for (final Direction fp10 : Direction.values()) {
bjt.updateNeighborsAt(fk.relative(fp10), this);
}
this.updatePowerStrength(bjt, fk, byg1);
for (final Direction fp11 : Direction.Plane.HORIZONTAL) {
this.checkCornerChangeAt(bjt, fk.relative(fp11));
}
for (final Direction fp11 : Direction.Plane.HORIZONTAL) {
final BlockPos fk2 = fk.relative(fp11);
if (bjt.getBlockState(fk2).isRedstoneConductor(bjt, fk2)) {
this.checkCornerChangeAt(bjt, fk2.above());
}
else {
this.checkCornerChangeAt(bjt, fk2.below());
}
}
}
private int checkTarget(final int integer, final BlockState byg) {
if (byg.getBlock() != this) {
return integer;
}
final int integer2 = byg.<Integer>getValue((Property<Integer>)RedStoneWireBlock.POWER);
if (integer2 > integer) {
return integer2;
}
return integer;
}
@Override
public void neighborChanged(final BlockState byg, final Level bjt, final BlockPos fk3, final Block bpe, final BlockPos fk5, final boolean boolean6) {
if (bjt.isClientSide) {
return;
}
if (byg.canSurvive(bjt, fk3)) {
this.updatePowerStrength(bjt, fk3, byg);
}
else {
Block.dropResources(byg, bjt, fk3);
bjt.removeBlock(fk3, false);
}
}
@Override
public int getDirectSignal(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
if (!this.shouldSignal) {
return 0;
}
return byg.getSignal(bjd, fk, fp);
}
@Override
public int getSignal(final BlockState byg, final BlockGetter bjd, final BlockPos fk, final Direction fp) {
if (!this.shouldSignal) {
return 0;
}
final int integer6 = byg.<Integer>getValue((Property<Integer>)RedStoneWireBlock.POWER);
if (integer6 == 0) {
return 0;
}
if (fp == Direction.UP) {
return integer6;
}
final EnumSet<Direction> enumSet7 = EnumSet.<Direction>noneOf(Direction.class);
for (final Direction fp2 : Direction.Plane.HORIZONTAL) {
if (this.isPowerSourceAt(bjd, fk, fp2)) {
enumSet7.add(fp2);
}
}
if (fp.getAxis().isHorizontal() && enumSet7.isEmpty()) {
return integer6;
}
if (enumSet7.contains(fp) && !enumSet7.contains(fp.getCounterClockWise()) && !enumSet7.contains(fp.getClockWise())) {
return integer6;
}
return 0;
}
private boolean isPowerSourceAt(final BlockGetter bjd, final BlockPos fk, final Direction fp) {
final BlockPos fk2 = fk.relative(fp);
final BlockState byg6 = bjd.getBlockState(fk2);
final boolean boolean7 = byg6.isRedstoneConductor(bjd, fk2);
final BlockPos fk3 = fk.above();
final boolean boolean8 = bjd.getBlockState(fk3).isRedstoneConductor(bjd, fk3);
return (!boolean8 && boolean7 && shouldConnectTo(bjd, fk2.above())) || shouldConnectTo(byg6, fp) || (byg6.getBlock() == Blocks.REPEATER && byg6.<Boolean>getValue((Property<Boolean>)DiodeBlock.POWERED) && byg6.<Comparable>getValue((Property<Comparable>)DiodeBlock.FACING) == fp) || (!boolean7 && shouldConnectTo(bjd, fk2.below()));
}
protected static boolean shouldConnectTo(final BlockGetter bjd, final BlockPos fk) {
return shouldConnectTo(bjd.getBlockState(fk));
}
protected static boolean shouldConnectTo(final BlockState byg) {
return shouldConnectTo(byg, null);
}
protected static boolean shouldConnectTo(final BlockState byg, @Nullable final Direction fp) {
final Block bpe3 = byg.getBlock();
if (bpe3 == Blocks.REDSTONE_WIRE) {
return true;
}
if (byg.getBlock() == Blocks.REPEATER) {
final Direction fp2 = byg.<Direction>getValue((Property<Direction>)RepeaterBlock.FACING);
return fp2 == fp || fp2.getOpposite() == fp;
}
if (Blocks.OBSERVER == byg.getBlock()) {
return fp == byg.<Direction>getValue((Property<Direction>)ObserverBlock.FACING);
}
return byg.isSignalSource() && fp != null;
}
@Override
public boolean isSignalSource(final BlockState byg) {
return this.shouldSignal;
}
public static int getColorForData(final int integer) {
final float float2 = integer / 15.0f;
float float3 = float2 * 0.6f + 0.4f;
if (integer == 0) {
float3 = 0.3f;
}
float float4 = float2 * float2 * 0.7f - 0.5f;
float float5 = float2 * float2 * 0.6f - 0.7f;
if (float4 < 0.0f) {
float4 = 0.0f;
}
if (float5 < 0.0f) {
float5 = 0.0f;
}
final int integer2 = Mth.clamp((int)(float3 * 255.0f), 0, 255);
final int integer3 = Mth.clamp((int)(float4 * 255.0f), 0, 255);
final int integer4 = Mth.clamp((int)(float5 * 255.0f), 0, 255);
return 0xFF000000 | integer2 << 16 | integer3 << 8 | integer4;
}
@Override
public void animateTick(final BlockState byg, final Level bjt, final BlockPos fk, final Random random) {
final int integer6 = byg.<Integer>getValue((Property<Integer>)RedStoneWireBlock.POWER);
if (integer6 == 0) {
return;
}
final double double7 = fk.getX() + 0.5 + (random.nextFloat() - 0.5) * 0.2;
final double double8 = fk.getY() + 0.0625f;
final double double9 = fk.getZ() + 0.5 + (random.nextFloat() - 0.5) * 0.2;
final float float13 = integer6 / 15.0f;
final float float14 = float13 * 0.6f + 0.4f;
final float float15 = Math.max(0.0f, float13 * float13 * 0.7f - 0.5f);
final float float16 = Math.max(0.0f, float13 * float13 * 0.6f - 0.7f);
bjt.addParticle(new DustParticleOptions(float14, float15, float16, 1.0f), double7, double8, double9, 0.0, 0.0, 0.0);
}
@Override
public BlockState rotate(final BlockState byg, final Rotation btr) {
switch (btr) {
case CLOCKWISE_180: {
return (((((AbstractStateHolder<O, BlockState>)byg).setValue(RedStoneWireBlock.NORTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.SOUTH))).setValue(RedStoneWireBlock.EAST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.WEST))).setValue(RedStoneWireBlock.SOUTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.NORTH))).<RedstoneSide, Comparable>setValue(RedStoneWireBlock.WEST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.EAST));
}
case COUNTERCLOCKWISE_90: {
return (((((AbstractStateHolder<O, BlockState>)byg).setValue(RedStoneWireBlock.NORTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.EAST))).setValue(RedStoneWireBlock.EAST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.SOUTH))).setValue(RedStoneWireBlock.SOUTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.WEST))).<RedstoneSide, Comparable>setValue(RedStoneWireBlock.WEST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.NORTH));
}
case CLOCKWISE_90: {
return (((((AbstractStateHolder<O, BlockState>)byg).setValue(RedStoneWireBlock.NORTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.WEST))).setValue(RedStoneWireBlock.EAST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.NORTH))).setValue(RedStoneWireBlock.SOUTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.EAST))).<RedstoneSide, Comparable>setValue(RedStoneWireBlock.WEST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.SOUTH));
}
default: {
return byg;
}
}
}
@Override
public BlockState mirror(final BlockState byg, final Mirror bsr) {
switch (bsr) {
case LEFT_RIGHT: {
return (((AbstractStateHolder<O, BlockState>)byg).setValue(RedStoneWireBlock.NORTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.SOUTH))).<RedstoneSide, Comparable>setValue(RedStoneWireBlock.SOUTH, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.NORTH));
}
case FRONT_BACK: {
return (((AbstractStateHolder<O, BlockState>)byg).setValue(RedStoneWireBlock.EAST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.WEST))).<RedstoneSide, Comparable>setValue(RedStoneWireBlock.WEST, (Comparable)byg.<V>getValue((Property<V>)RedStoneWireBlock.EAST));
}
default: {
return super.mirror(byg, bsr);
}
}
}
@Override
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
a.add(RedStoneWireBlock.NORTH, RedStoneWireBlock.EAST, RedStoneWireBlock.SOUTH, RedStoneWireBlock.WEST, RedStoneWireBlock.POWER);
}
static {
NORTH = BlockStateProperties.NORTH_REDSTONE;
EAST = BlockStateProperties.EAST_REDSTONE;
SOUTH = BlockStateProperties.SOUTH_REDSTONE;
WEST = BlockStateProperties.WEST_REDSTONE;
POWER = BlockStateProperties.POWER;
PROPERTY_BY_DIRECTION = Maps.<Direction, Object>newEnumMap(ImmutableMap.<Direction, EnumProperty<RedstoneSide>>of(Direction.NORTH, RedStoneWireBlock.NORTH, Direction.EAST, RedStoneWireBlock.EAST, Direction.SOUTH, RedStoneWireBlock.SOUTH, Direction.WEST, RedStoneWireBlock.WEST));
SHAPE_BY_INDEX = new VoxelShape[] { Block.box(3.0, 0.0, 3.0, 13.0, 1.0, 13.0), Block.box(3.0, 0.0, 3.0, 13.0, 1.0, 16.0), Block.box(0.0, 0.0, 3.0, 13.0, 1.0, 13.0), Block.box(0.0, 0.0, 3.0, 13.0, 1.0, 16.0), Block.box(3.0, 0.0, 0.0, 13.0, 1.0, 13.0), Block.box(3.0, 0.0, 0.0, 13.0, 1.0, 16.0), Block.box(0.0, 0.0, 0.0, 13.0, 1.0, 13.0), Block.box(0.0, 0.0, 0.0, 13.0, 1.0, 16.0), Block.box(3.0, 0.0, 3.0, 16.0, 1.0, 13.0), Block.box(3.0, 0.0, 3.0, 16.0, 1.0, 16.0), Block.box(0.0, 0.0, 3.0, 16.0, 1.0, 13.0), Block.box(0.0, 0.0, 3.0, 16.0, 1.0, 16.0), Block.box(3.0, 0.0, 0.0, 16.0, 1.0, 13.0), Block.box(3.0, 0.0, 0.0, 16.0, 1.0, 16.0), Block.box(0.0, 0.0, 0.0, 16.0, 1.0, 13.0), Block.box(0.0, 0.0, 0.0, 16.0, 1.0, 16.0) };
}
}