package net.minecraft.server;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.koloboke.collect.set.hash.HashObjSets;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockRedstoneWire extends Block {
public static final BlockStateEnum<BlockRedstoneWire.EnumRedstoneWireConnection> NORTH = BlockStateEnum.of("north", BlockRedstoneWire.EnumRedstoneWireConnection.class);
public static final BlockStateEnum<BlockRedstoneWire.EnumRedstoneWireConnection> EAST = BlockStateEnum.of("east", BlockRedstoneWire.EnumRedstoneWireConnection.class);
public static final BlockStateEnum<BlockRedstoneWire.EnumRedstoneWireConnection> SOUTH = BlockStateEnum.of("south", BlockRedstoneWire.EnumRedstoneWireConnection.class);
public static final BlockStateEnum<BlockRedstoneWire.EnumRedstoneWireConnection> WEST = BlockStateEnum.of("west", BlockRedstoneWire.EnumRedstoneWireConnection.class);
public static final BlockStateInteger POWER = BlockStateInteger.of("power", 0, 15);
protected static final AxisAlignedBB[] f = new AxisAlignedBB[] { new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.8125D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.1875D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.1875D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 0.8125D), new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.0625D, 1.0D)};
private boolean g = true;
private final Set<BlockPosition> B = HashObjSets.newMutableSet(); private final Set<BlockPosition> blocksToUpdate = B; // Paper - OBFHELPER
public BlockRedstoneWire() {
super(Material.ORIENTABLE);
this.y(this.blockStateList.getBlockData().set(BlockRedstoneWire.NORTH, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.EAST, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.SOUTH, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.WEST, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.POWER, Integer.valueOf(0)));
}
@Override
public AxisAlignedBB b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
return BlockRedstoneWire.f[z(iblockdata.b(iblockaccess, blockposition))];
}
private static int z(IBlockData iblockdata) {
int i = 0;
boolean flag = iblockdata.get(BlockRedstoneWire.NORTH) != BlockRedstoneWire.EnumRedstoneWireConnection.NONE;
boolean flag1 = iblockdata.get(BlockRedstoneWire.EAST) != BlockRedstoneWire.EnumRedstoneWireConnection.NONE;
boolean flag2 = iblockdata.get(BlockRedstoneWire.SOUTH) != BlockRedstoneWire.EnumRedstoneWireConnection.NONE;
boolean flag3 = iblockdata.get(BlockRedstoneWire.WEST) != BlockRedstoneWire.EnumRedstoneWireConnection.NONE;
if (flag || flag2 && !flag && !flag1 && !flag3) {
i |= 1 << EnumDirection.NORTH.get2DRotationValue();
}
if (flag1 || flag3 && !flag && !flag1 && !flag2) {
i |= 1 << EnumDirection.EAST.get2DRotationValue();
}
if (flag2 || flag && !flag1 && !flag2 && !flag3) {
i |= 1 << EnumDirection.SOUTH.get2DRotationValue();
}
if (flag3 || flag1 && !flag && !flag2 && !flag3) {
i |= 1 << EnumDirection.WEST.get2DRotationValue();
}
return i;
}
@Override
public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
iblockdata = iblockdata.set(BlockRedstoneWire.WEST, this.b(iblockaccess, blockposition, EnumDirection.WEST));
iblockdata = iblockdata.set(BlockRedstoneWire.EAST, this.b(iblockaccess, blockposition, EnumDirection.EAST));
iblockdata = iblockdata.set(BlockRedstoneWire.NORTH, this.b(iblockaccess, blockposition, EnumDirection.NORTH));
iblockdata = iblockdata.set(BlockRedstoneWire.SOUTH, this.b(iblockaccess, blockposition, EnumDirection.SOUTH));
return iblockdata;
}
private BlockRedstoneWire.EnumRedstoneWireConnection b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
BlockPosition blockposition1 = blockposition.shift(enumdirection);
IBlockData iblockdata = iblockaccess.getType(blockposition.shift(enumdirection));
if (!a(iblockaccess.getType(blockposition1), enumdirection) && (iblockdata.m() || !i(iblockaccess.getType(blockposition1.down())))) {
IBlockData iblockdata1 = iblockaccess.getType(blockposition.up());
if (!iblockdata1.m()) {
boolean flag = iblockaccess.getType(blockposition1).r() || iblockaccess.getType(blockposition1).getBlock() == Blocks.GLOWSTONE;
if (flag && i(iblockaccess.getType(blockposition1.up()))) {
if (iblockdata.l()) {
return BlockRedstoneWire.EnumRedstoneWireConnection.UP;
}
return BlockRedstoneWire.EnumRedstoneWireConnection.SIDE;
}
}
return BlockRedstoneWire.EnumRedstoneWireConnection.NONE;
} else {
return BlockRedstoneWire.EnumRedstoneWireConnection.SIDE;
}
}
@Override
@Nullable
public AxisAlignedBB a(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
return BlockRedstoneWire.k;
}
@Override
public boolean b(IBlockData iblockdata) {
return false;
}
@Override
public boolean c(IBlockData iblockdata) {
return false;
}
@Override
public boolean canPlace(World world, BlockPosition blockposition) {
return world.getType(blockposition.down()).r() || world.getType(blockposition.down()).getBlock() == Blocks.GLOWSTONE;
}
private IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) {
iblockdata = this.a(world, blockposition, blockposition, iblockdata);
ArrayList arraylist = Lists.newArrayList(this.B);
this.B.clear();
Iterator iterator = arraylist.iterator();
while (iterator.hasNext()) {
BlockPosition blockposition1 = (BlockPosition) iterator.next();
world.applyPhysics(blockposition1, this, false);
}
return iblockdata;
}
private IBlockData a(World world, BlockPosition blockposition, BlockPosition blockposition1, IBlockData iblockdata) {
IBlockData iblockdata1 = iblockdata;
int i = iblockdata.get(BlockRedstoneWire.POWER).intValue();
byte b0 = 0;
int j = this.getPower(world, blockposition1, b0);
this.g = false;
int k = world.z(blockposition);
this.g = true;
if (k > 0 && k > j - 1) {
j = k;
}
int l = 0;
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
while (iterator.hasNext()) {
EnumDirection enumdirection = (EnumDirection) iterator.next();
BlockPosition blockposition2 = blockposition.shift(enumdirection);
boolean flag = blockposition2.getX() != blockposition1.getX() || blockposition2.getZ() != blockposition1.getZ();
if (flag) {
l = this.getPower(world, blockposition2, l);
}
if (world.getType(blockposition2).m() && !world.getType(blockposition.up()).m()) {
if (flag && blockposition.getY() >= blockposition1.getY()) {
l = this.getPower(world, blockposition2.up(), l);
}
} else if (!world.getType(blockposition2).m() && flag && blockposition.getY() <= blockposition1.getY()) {
l = this.getPower(world, blockposition2.down(), l);
}
}
if (l > j) {
j = l - 1;
} else if (j > 0) {
--j;
} else {
j = 0;
}
if (k > j - 1) {
j = k;
}
// CraftBukkit start
if (i != j) {
BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j);
world.getServer().getPluginManager().callEvent(event);
j = event.getNewCurrent();
}
// CraftBukkit end
if (i != j) {
iblockdata = iblockdata.set(BlockRedstoneWire.POWER, Integer.valueOf(j));
if (world.getType(blockposition) == iblockdata1) {
world.setTypeAndData(blockposition, iblockdata, 2);
}
this.B.add(blockposition);
// Paper start - Old TNT cannon behaviors
if (world.paperConfig.oldCannonBehaviors) {
this.blocksToUpdate.add(blockposition.shift(EnumDirection.WEST));
this.blocksToUpdate.add(blockposition.shift(EnumDirection.EAST));
this.blocksToUpdate.add(blockposition.shift(EnumDirection.DOWN));
this.blocksToUpdate.add(blockposition.shift(EnumDirection.UP));
this.blocksToUpdate.add(blockposition.shift(EnumDirection.NORTH));
this.blocksToUpdate.add(blockposition.shift(EnumDirection.SOUTH));
return iblockdata;
}
// Paper end
EnumDirection[] aenumdirection = EnumDirection.values();
int i1 = aenumdirection.length;
for (int j1 = 0; j1 < i1; ++j1) {
EnumDirection enumdirection1 = aenumdirection[j1];
this.B.add(blockposition.shift(enumdirection1));
}
}
return iblockdata;
}
private void b(World world, BlockPosition blockposition) {
if (world.getType(blockposition).getBlock() == this) {
world.applyPhysics(blockposition, this, false);
if (world.paperConfig.oldCannonBehaviors) {
world.applyPhysics(blockposition.shift(EnumDirection.WEST), this, false);
world.applyPhysics(blockposition.shift(EnumDirection.EAST), this, false);
world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this, false);
world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this, false);
world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this, false);
world.applyPhysics(blockposition.shift(EnumDirection.UP), this, false);
return;
}
// Paper end
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
for (int j = 0; j < i; ++j) {
EnumDirection enumdirection = aenumdirection[j];
world.applyPhysics(blockposition.shift(enumdirection), this, false);
}
}
}
@Override
public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
if (!world.isClientSide) {
this.e(world, blockposition, iblockdata);
Iterator iterator = EnumDirection.EnumDirectionLimit.VERTICAL.iterator();
EnumDirection enumdirection;
while (iterator.hasNext()) {
enumdirection = (EnumDirection) iterator.next();
world.applyPhysics(blockposition.shift(enumdirection), this, false);
}
iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
while (iterator.hasNext()) {
enumdirection = (EnumDirection) iterator.next();
this.b(world, blockposition.shift(enumdirection));
}
iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
while (iterator.hasNext()) {
enumdirection = (EnumDirection) iterator.next();
BlockPosition blockposition1 = blockposition.shift(enumdirection);
if (world.getType(blockposition1).m()) {
this.b(world, blockposition1.up());
} else {
this.b(world, blockposition1.down());
}
}
}
}
@Override
public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
super.remove(world, blockposition, iblockdata);
if (!world.isClientSide) {
EnumDirection[] aenumdirection = EnumDirection.values();
int i = aenumdirection.length;
for (int j = 0; j < i; ++j) {
EnumDirection enumdirection = aenumdirection[j];
world.applyPhysics(blockposition.shift(enumdirection), this, false);
}
this.e(world, blockposition, iblockdata);
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
EnumDirection enumdirection1;
while (iterator.hasNext()) {
enumdirection1 = (EnumDirection) iterator.next();
this.b(world, blockposition.shift(enumdirection1));
}
iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
while (iterator.hasNext()) {
enumdirection1 = (EnumDirection) iterator.next();
BlockPosition blockposition1 = blockposition.shift(enumdirection1);
if (world.getType(blockposition1).m()) {
this.b(world, blockposition1.up());
} else {
this.b(world, blockposition1.down());
}
}
}
}
public int getPower(World world, BlockPosition blockposition, int i) {
if (world.getType(blockposition).getBlock() != this) {
return i;
} else {
int j = world.getType(blockposition).get(BlockRedstoneWire.POWER).intValue();
return j > i ? j : i;
}
}
@Override
public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Block block, BlockPosition blockposition1) {
if (!world.isClientSide) {
if (this.canPlace(world, blockposition)) {
this.e(world, blockposition, iblockdata);
} else {
this.b(world, blockposition, iblockdata, 0);
world.setAir(blockposition);
}
}
}
@Override
public Item getDropType(IBlockData iblockdata, Random random, int i) {
return Items.REDSTONE;
}
@Override
public int c(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
return !this.g ? 0 : iblockdata.a(iblockaccess, blockposition, enumdirection);
}
@Override
public int b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
if (!this.g) {
return 0;
} else {
int i = iblockdata.get(BlockRedstoneWire.POWER).intValue();
if (i == 0) {
return 0;
} else if (enumdirection == EnumDirection.UP) {
return i;
} else {
EnumSet enumset = EnumSet.noneOf(EnumDirection.class);
Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator();
while (iterator.hasNext()) {
EnumDirection enumdirection1 = (EnumDirection) iterator.next();
if (this.c(iblockaccess, blockposition, enumdirection1)) {
enumset.add(enumdirection1);
}
}
if (enumdirection.k().c() && enumset.isEmpty()) {
return i;
} else if (enumset.contains(enumdirection) && !enumset.contains(enumdirection.f()) && !enumset.contains(enumdirection.e())) {
return i;
} else {
return 0;
}
}
}
}
private boolean c(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) {
BlockPosition blockposition1 = blockposition.shift(enumdirection);
IBlockData iblockdata = iblockaccess.getType(blockposition1);
boolean flag = iblockdata.m();
boolean flag1 = iblockaccess.getType(blockposition.up()).m();
return !flag1 && flag && c(iblockaccess, blockposition1.up()) ? true : (a(iblockdata, enumdirection) ? true : (iblockdata.getBlock() == Blocks.POWERED_REPEATER && iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection ? true : !flag && c(iblockaccess, blockposition1.down())));
}
protected static boolean c(IBlockAccess iblockaccess, BlockPosition blockposition) {
return i(iblockaccess.getType(blockposition));
}
protected static boolean i(IBlockData iblockdata) {
return a(iblockdata, (EnumDirection) null);
}
protected static boolean a(IBlockData iblockdata, @Nullable EnumDirection enumdirection) {
Block block = iblockdata.getBlock();
if (block == Blocks.REDSTONE_WIRE) {
return true;
} else if (Blocks.UNPOWERED_REPEATER.E(iblockdata)) {
EnumDirection enumdirection1 = iblockdata.get(BlockRepeater.FACING);
return enumdirection1 == enumdirection || enumdirection1.opposite() == enumdirection;
} else {
return Blocks.dk == iblockdata.getBlock() ? enumdirection == iblockdata.get(BlockObserver.FACING) : iblockdata.n() && enumdirection != null;
}
}
@Override
public boolean isPowerSource(IBlockData iblockdata) {
return this.g;
}
@Override
public ItemStack a(World world, BlockPosition blockposition, IBlockData iblockdata) {
return new ItemStack(Items.REDSTONE);
}
@Override
public IBlockData fromLegacyData(int i) {
return this.getBlockData().set(BlockRedstoneWire.POWER, Integer.valueOf(i));
}
@Override
public int toLegacyData(IBlockData iblockdata) {
return iblockdata.get(BlockRedstoneWire.POWER).intValue();
}
@Override
public IBlockData a(IBlockData iblockdata, EnumBlockRotation enumblockrotation) {
switch (enumblockrotation) {
case CLOCKWISE_180:
return iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH)).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST)).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH)).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST));
case COUNTERCLOCKWISE_90:
return iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.EAST)).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.SOUTH)).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.WEST)).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.NORTH));
case CLOCKWISE_90:
return iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.WEST)).set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.NORTH)).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.EAST)).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.SOUTH));
default:
return iblockdata;
}
}
@Override
public IBlockData a(IBlockData iblockdata, EnumBlockMirror enumblockmirror) {
switch (enumblockmirror) {
case LEFT_RIGHT:
return iblockdata.set(BlockRedstoneWire.NORTH, iblockdata.get(BlockRedstoneWire.SOUTH)).set(BlockRedstoneWire.SOUTH, iblockdata.get(BlockRedstoneWire.NORTH));
case FRONT_BACK:
return iblockdata.set(BlockRedstoneWire.EAST, iblockdata.get(BlockRedstoneWire.WEST)).set(BlockRedstoneWire.WEST, iblockdata.get(BlockRedstoneWire.EAST));
default:
return super.a(iblockdata, enumblockmirror);
}
}
@Override
protected BlockStateList getStateList() {
return new BlockStateList(this, new IBlockState[] { BlockRedstoneWire.NORTH, BlockRedstoneWire.EAST, BlockRedstoneWire.SOUTH, BlockRedstoneWire.WEST, BlockRedstoneWire.POWER});
}
static enum EnumRedstoneWireConnection implements INamable {
UP("up"), SIDE("side"), NONE("none");
private final String d;
private EnumRedstoneWireConnection(String s) {
this.d = s;
}
@Override
public String toString() {
return this.getName();
}
@Override
public String getName() {
return this.d;
}
}
}