package micdoodle8.mods.galacticraft.core.util; import net.minecraft.block.Block; import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; public class RedstoneUtil { /** * Returns true if the block is being directly powered with a redstone wire, lever, etc * (generally only used by actual redstone components for onward transmission of redstone signal) */ public static boolean isBlockReceivingDirectRedstone(World w, BlockPos pos) { if (w == null) { return false; } // Check up/down without chunk load test first if (getStrongPower(w, pos.down(), EnumFacing.DOWN) > 0) { return true; } if (getStrongPower(w, pos.up(), EnumFacing.UP) > 0) { return true; } for (EnumFacing facing : EnumFacing.HORIZONTALS) { if (getStrongPower_NoChunkLoad(w, pos.offset(facing, 1), facing) > 0) { return true; } } return false; } /** * Is this block powering in the specified direction Args: x, y, z, direction */ public static int getStrongPower(World w, BlockPos pos, EnumFacing side) { IBlockState bs = w.getBlockState(pos); return bs.getBlock().getStrongPower(w, pos, bs, side); } public static int getStrongPower_NoChunkLoad(World w, BlockPos pos, EnumFacing side) { if (!w.isBlockLoaded(pos, false)) { return 0; } IBlockState bs = w.getBlockState(pos); return bs.getBlock().getStrongPower(w, pos, bs, side); } /** * Returns true if the block is being INDIRECTLY powered e.g by redstone passing through another block * (similar to how a vanilla piston or redstone lamp responds) * * INEFFICIENT: (almost as bad as Vanilla!) examines redstone status of 30 nearby blocks if there is no redstone power * * Note: if the calling block is itself a redstone emitter (!!) its redstone output to neighbours will be ignored */ public static boolean isBlockReceivingRedstone(World w, BlockPos pos) { if (w == null) { return false; } // Check up/down without chunk load test first if (getRedstonePowerIndirect(w, pos.up(1), EnumFacing.UP) > 0) { return true; } if (getRedstonePowerIndirect(w, pos.down(1), EnumFacing.DOWN) > 0) { return true; } for (EnumFacing facing : EnumFacing.HORIZONTALS) { if (getRedstonePowerIndirect_NoChunkLoad(w, pos.offset(facing, 1), facing) > 0) { return true; } } return false; } public static int getRedstonePowerIndirect_NoChunkLoad(World w, BlockPos pos, EnumFacing side) { if (!w.isBlockLoaded(pos, false)) { return 0; } return getRedstonePowerIndirect(w, pos, side); } public static int getRedstonePowerIndirect(World w, BlockPos pos, EnumFacing facing) { IBlockState bs = w.getBlockState(pos); Block block = bs.getBlock(); if (block instanceof BlockAir) { return 0; } return block.shouldCheckWeakPower(w, pos, facing) ? getNeighbourPower_NoChunkLoad(w, pos, facing.getOpposite()) : block.getWeakPower(w, pos, bs, facing); } /** * Similar to the vanilla method getStrongPower(BlockPos pos) but more efficient - doesn't backtrack, so 15% faster * (also the low level code here is faster...) */ public static int getNeighbourPower_NoChunkLoad(World w, BlockPos pos, EnumFacing skip) { int i = 0; int p; IBlockState bs; BlockPos sidePos; if (skip != EnumFacing.DOWN) { sidePos = pos.add(0, -1, 0); bs = w.getBlockState(sidePos); i = bs.getBlock().getStrongPower(w, sidePos, bs, EnumFacing.DOWN); if (i >= 15) { return i; } } if (skip != EnumFacing.UP) { sidePos = pos.add(0, 1, 0); bs = w.getBlockState(sidePos); p = bs.getBlock().getStrongPower(w, sidePos, bs, EnumFacing.UP); if (p >= 15) { return p; } if (p > i) i = p; } for (EnumFacing side : EnumFacing.HORIZONTALS) { if (side == skip) { continue; } //This is a slightly faster pos.offset(side) sidePos = pos.add(side.getFrontOffsetX(), 0, side.getFrontOffsetZ()); if (!w.isBlockLoaded(sidePos, false)) { continue; } bs = w.getBlockState(sidePos); p = bs.getBlock().getStrongPower(w, sidePos, bs, side); if (p >= 15) { return p; } if (p > i) i = p; } return i; } }