package net.minecraft.block; import java.util.List; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.BlockPistonStructureHelper; import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityPiston; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; /**+ * This portion of EaglercraftX contains deobfuscated Minecraft 1.8 source code. * * Minecraft 1.8.8 bytecode is (c) 2015 Mojang AB. "Do not distribute!" * Mod Coder Pack v9.18 deobfuscation configs are (c) Copyright by the MCP Team * * EaglercraftX 1.8 patch files (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ public class BlockPistonBase extends Block { public static final PropertyDirection FACING = PropertyDirection.create("facing"); public static final PropertyBool EXTENDED = PropertyBool.create("extended"); private final boolean isSticky; public BlockPistonBase(boolean isSticky) { super(Material.piston); this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH) .withProperty(EXTENDED, Boolean.valueOf(false))); this.isSticky = isSticky; this.setStepSound(soundTypePiston); this.setHardness(0.5F); this.setCreativeTab(CreativeTabs.tabRedstone); } /**+ * Used to determine ambient occlusion and culling when * rebuilding chunks for render */ public boolean isOpaqueCube() { return false; } /**+ * Called by ItemBlocks after a block is set in the world, to * allow post-place logic */ public void onBlockPlacedBy(World world, BlockPos blockpos, IBlockState iblockstate, EntityLivingBase entitylivingbase, ItemStack var5) { world.setBlockState(blockpos, iblockstate.withProperty(FACING, getFacingFromEntity(world, blockpos, entitylivingbase)), 2); } /**+ * Called by ItemBlocks just before a block is actually set in * the world, to allow for adjustments to the IBlockstate */ public IBlockState onBlockPlaced(World world, BlockPos blockpos, EnumFacing var3, float var4, float var5, float var6, int var7, EntityLivingBase entitylivingbase) { return this.getDefaultState().withProperty(FACING, getFacingFromEntity(world, blockpos, entitylivingbase)) .withProperty(EXTENDED, Boolean.valueOf(false)); } private void checkForMove(World worldIn, BlockPos pos, IBlockState state) { EnumFacing enumfacing = (EnumFacing) state.getValue(FACING); boolean flag = this.shouldBeExtended(worldIn, pos, enumfacing); if (flag && !((Boolean) state.getValue(EXTENDED)).booleanValue()) { if ((new BlockPistonStructureHelper(worldIn, pos, enumfacing, true)).canMove()) { worldIn.addBlockEvent(pos, this, 0, enumfacing.getIndex()); } } else if (!flag && ((Boolean) state.getValue(EXTENDED)).booleanValue()) { worldIn.setBlockState(pos, state.withProperty(EXTENDED, Boolean.valueOf(false)), 2); worldIn.addBlockEvent(pos, this, 1, enumfacing.getIndex()); } } private boolean shouldBeExtended(World worldIn, BlockPos pos, EnumFacing facing) { for (EnumFacing enumfacing : EnumFacing.values()) { if (enumfacing != facing && worldIn.isSidePowered(pos.offset(enumfacing), enumfacing)) { return true; } } if (worldIn.isSidePowered(pos, EnumFacing.DOWN)) { return true; } else { BlockPos blockpos = pos.up(); for (EnumFacing enumfacing1 : EnumFacing.values()) { if (enumfacing1 != EnumFacing.DOWN && worldIn.isSidePowered(blockpos.offset(enumfacing1), enumfacing1)) { return true; } } return false; } } /**+ * Called on both Client and Server when World#addBlockEvent is * called */ public boolean onBlockEventReceived(World world, BlockPos blockpos, IBlockState iblockstate, int i, int j) { EnumFacing enumfacing = (EnumFacing) iblockstate.getValue(FACING); if (i == 0) { if (!this.doMove(world, blockpos, enumfacing, true)) { return false; } world.setBlockState(blockpos, iblockstate.withProperty(EXTENDED, Boolean.valueOf(true)), 2); world.playSoundEffect((double) blockpos.getX() + 0.5D, (double) blockpos.getY() + 0.5D, (double) blockpos.getZ() + 0.5D, "tile.piston.out", 0.5F, world.rand.nextFloat() * 0.25F + 0.6F); } else if (i == 1) { TileEntity tileentity1 = world.getTileEntity(blockpos.offset(enumfacing)); if (tileentity1 instanceof TileEntityPiston) { ((TileEntityPiston) tileentity1).clearPistonTileEntity(); } world.setBlockState(blockpos, Blocks.piston_extension.getDefaultState().withProperty(BlockPistonMoving.FACING, enumfacing) .withProperty(BlockPistonMoving.TYPE, this.isSticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT), 3); world.setTileEntity(blockpos, BlockPistonMoving.newTileEntity(this.getStateFromMeta(j), enumfacing, false, true)); if (this.isSticky) { BlockPos blockpos1 = blockpos.add(enumfacing.getFrontOffsetX() * 2, enumfacing.getFrontOffsetY() * 2, enumfacing.getFrontOffsetZ() * 2); Block block = world.getBlockState(blockpos1).getBlock(); boolean flag1 = false; if (block == Blocks.piston_extension) { TileEntity tileentity = world.getTileEntity(blockpos1); if (tileentity instanceof TileEntityPiston) { TileEntityPiston tileentitypiston = (TileEntityPiston) tileentity; if (tileentitypiston.getFacing() == enumfacing && tileentitypiston.isExtending()) { tileentitypiston.clearPistonTileEntity(); flag1 = true; } } } if (!flag1 && block.getMaterial() != Material.air && canPush(block, world, blockpos1, enumfacing.getOpposite(), false) && (block.getMobilityFlag() == 0 || block == Blocks.piston || block == Blocks.sticky_piston)) { this.doMove(world, blockpos, enumfacing, false); } } else { world.setBlockToAir(blockpos.offset(enumfacing)); } world.playSoundEffect((double) blockpos.getX() + 0.5D, (double) blockpos.getY() + 0.5D, (double) blockpos.getZ() + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat() * 0.15F + 0.6F); } return true; } public void setBlockBoundsBasedOnState(IBlockAccess iblockaccess, BlockPos blockpos) { IBlockState iblockstate = iblockaccess.getBlockState(blockpos); if (iblockstate.getBlock() == this && ((Boolean) iblockstate.getValue(EXTENDED)).booleanValue()) { float f = 0.25F; EnumFacing enumfacing = (EnumFacing) iblockstate.getValue(FACING); if (enumfacing != null) { switch (enumfacing) { case DOWN: this.setBlockBounds(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F); break; case UP: this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); break; case NORTH: this.setBlockBounds(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F); break; case SOUTH: this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F); break; case WEST: this.setBlockBounds(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); break; case EAST: this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F); } } } else { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); } } /**+ * Sets the block's bounds for rendering it as an item */ public void setBlockBoundsForItemRender() { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); } /**+ * Add all collision boxes of this Block to the list that * intersect with the given mask. */ public void addCollisionBoxesToList(World world, BlockPos blockpos, IBlockState iblockstate, AxisAlignedBB axisalignedbb, List list, Entity entity) { this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); super.addCollisionBoxesToList(world, blockpos, iblockstate, axisalignedbb, list, entity); } public AxisAlignedBB getCollisionBoundingBox(World world, BlockPos blockpos, IBlockState iblockstate) { this.setBlockBoundsBasedOnState(world, blockpos); return super.getCollisionBoundingBox(world, blockpos, iblockstate); } public boolean isFullCube() { return false; } public static EnumFacing getFacing(int meta) { int i = meta & 7; return i > 5 ? null : EnumFacing.getFront(i); } public static EnumFacing getFacingFromEntity(World worldIn, BlockPos clickedBlock, EntityLivingBase entityIn) { if (MathHelper.abs((float) entityIn.posX - (float) clickedBlock.getX()) < 2.0F && MathHelper.abs((float) entityIn.posZ - (float) clickedBlock.getZ()) < 2.0F) { double d0 = entityIn.posY + (double) entityIn.getEyeHeight(); if (d0 - (double) clickedBlock.getY() > 2.0D) { return EnumFacing.UP; } if ((double) clickedBlock.getY() - d0 > 0.0D) { return EnumFacing.DOWN; } } return entityIn.getHorizontalFacing().getOpposite(); } public static boolean canPush(Block blockIn, World worldIn, BlockPos pos, EnumFacing direction, boolean allowDestroy) { if (blockIn == Blocks.obsidian) { return false; } else if (!worldIn.getWorldBorder().contains(pos)) { return false; } else if (pos.getY() >= 0 && (direction != EnumFacing.DOWN || pos.getY() != 0)) { if (pos.getY() <= worldIn.getHeight() - 1 && (direction != EnumFacing.UP || pos.getY() != worldIn.getHeight() - 1)) { if (blockIn != Blocks.piston && blockIn != Blocks.sticky_piston) { if (blockIn.getBlockHardness(worldIn, pos) == -1.0F) { return false; } if (blockIn.getMobilityFlag() == 2) { return false; } if (blockIn.getMobilityFlag() == 1) { if (!allowDestroy) { return false; } return true; } } else if (((Boolean) worldIn.getBlockState(pos).getValue(EXTENDED)).booleanValue()) { return false; } return !(blockIn instanceof ITileEntityProvider); } else { return false; } } else { return false; } } private boolean doMove(World worldIn, BlockPos pos, EnumFacing direction, boolean extending) { if (!extending) { worldIn.setBlockToAir(pos.offset(direction)); } BlockPistonStructureHelper blockpistonstructurehelper = new BlockPistonStructureHelper(worldIn, pos, direction, extending); List list = blockpistonstructurehelper.getBlocksToMove(); List list1 = blockpistonstructurehelper.getBlocksToDestroy(); if (!blockpistonstructurehelper.canMove()) { return false; } else { int i = list.size() + list1.size(); Block[] ablock = new Block[i]; EnumFacing enumfacing = extending ? direction : direction.getOpposite(); for (int j = list1.size() - 1; j >= 0; --j) { BlockPos blockpos = (BlockPos) list1.get(j); Block block = worldIn.getBlockState(blockpos).getBlock(); block.dropBlockAsItem(worldIn, blockpos, worldIn.getBlockState(blockpos), 0); worldIn.setBlockToAir(blockpos); --i; ablock[i] = block; } for (int k = list.size() - 1; k >= 0; --k) { BlockPos blockpos2 = (BlockPos) list.get(k); IBlockState iblockstate = worldIn.getBlockState(blockpos2); Block block1 = iblockstate.getBlock(); block1.getMetaFromState(iblockstate); worldIn.setBlockToAir(blockpos2); blockpos2 = blockpos2.offset(enumfacing); worldIn.setBlockState(blockpos2, Blocks.piston_extension.getDefaultState().withProperty(FACING, direction), 4); worldIn.setTileEntity(blockpos2, BlockPistonMoving.newTileEntity(iblockstate, direction, extending, false)); --i; ablock[i] = block1; } BlockPos blockpos1 = pos.offset(direction); if (extending) { BlockPistonExtension.EnumPistonType blockpistonextension$enumpistontype = this.isSticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT; IBlockState iblockstate1 = Blocks.piston_head.getDefaultState() .withProperty(BlockPistonExtension.FACING, direction) .withProperty(BlockPistonExtension.TYPE, blockpistonextension$enumpistontype); IBlockState iblockstate2 = Blocks.piston_extension.getDefaultState() .withProperty(BlockPistonMoving.FACING, direction) .withProperty(BlockPistonMoving.TYPE, this.isSticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT); worldIn.setBlockState(blockpos1, iblockstate2, 4); worldIn.setTileEntity(blockpos1, BlockPistonMoving.newTileEntity(iblockstate1, direction, true, false)); } for (int l = list1.size() - 1; l >= 0; --l) { worldIn.notifyNeighborsOfStateChange((BlockPos) list1.get(l), ablock[i++]); } for (int i1 = list.size() - 1; i1 >= 0; --i1) { worldIn.notifyNeighborsOfStateChange((BlockPos) list.get(i1), ablock[i++]); } if (extending) { worldIn.notifyNeighborsOfStateChange(blockpos1, Blocks.piston_head); worldIn.notifyNeighborsOfStateChange(pos, this); } return true; } } /**+ * Possibly modify the given BlockState before rendering it on * an Entity (Minecarts, Endermen, ...) */ public IBlockState getStateForEntityRender(IBlockState var1) { return this.getDefaultState().withProperty(FACING, EnumFacing.UP); } /**+ * Convert the given metadata into a BlockState for this Block */ public IBlockState getStateFromMeta(int i) { return this.getDefaultState().withProperty(FACING, getFacing(i)).withProperty(EXTENDED, Boolean.valueOf((i & 8) > 0)); } /**+ * Convert the BlockState into the correct metadata value */ public int getMetaFromState(IBlockState iblockstate) { int i = 0; i = i | ((EnumFacing) iblockstate.getValue(FACING)).getIndex(); if (((Boolean) iblockstate.getValue(EXTENDED)).booleanValue()) { i |= 8; } return i; } protected BlockState createBlockState() { return new BlockState(this, new IProperty[] { FACING, EXTENDED }); } }