    001    package net.minecraft.block;
    002
    003    import java.util.Random;
    004    import net.minecraft.block.material.Material;
    005    import net.minecraft.creativetab.CreativeTabs;
    006    import net.minecraft.util.AxisAlignedBB;
    007    import net.minecraft.util.Direction;
    008    import net.minecraft.world.IBlockAccess;
    009    import net.minecraft.world.World;
    010
    011    import net.minecraftforge.common.ForgeDirection;
    012    import static net.minecraftforge.common.ForgeDirection.*;
    013
    014    public class BlockTripWireSource extends Block
    015    {
    016        public BlockTripWireSource(int par1)
    017        {
    018            super(par1, 172, Material.circuits);
    019            this.setCreativeTab(CreativeTabs.tabRedstone);
    020            this.setTickRandomly(true);
    021        }
    022
    023        /**
    024         * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
    025         * cleared to be reused)
    026         */
    027        public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
    028        {
    029            return null;
    030        }
    031
    032        /**
    033         * Is this block (a) opaque and (b) a full 1m cube?  This determines whether or not to render the shared face of two
    034         * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
    035         */
    036        public boolean isOpaqueCube()
    037        {
    038            return false;
    039        }
    040
    041        /**
    042         * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
    043         */
    044        public boolean renderAsNormalBlock()
    045        {
    046            return false;
    047        }
    048
    049        /**
    050         * The type of render function that is called for this block
    051         */
    052        public int getRenderType()
    053        {
    054            return 29;
    055        }
    056
    057        /**
    058         * How many world ticks before ticking
    059         */
    060        public int tickRate()
    061        {
    062            return 10;
    063        }
    064
    065        /**
    066         * checks to see if you can place this block can be placed on that side of a block: BlockLever overrides
    067         */
    068        public boolean canPlaceBlockOnSide(World par1World, int par2, int par3, int par4, int par5)
    069        {
    070            ForgeDirection dir = ForgeDirection.getOrientation(par5);
    071            return (dir == NORTH && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, NORTH)) ||
    072                   (dir == SOUTH && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, SOUTH)) ||
    073                   (dir == WEST  && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, WEST )) ||
    074                   (dir == EAST  && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, EAST ));
    075        }
    076
    077        /**
    078         * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
    079         */
    080        public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
    081        {
    082            return par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH) ||
    083                   par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH) ||
    084                   par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST ) ||
    085                   par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST );
    086        }
    087
    088        public int func_85104_a(World par1World, int par2, int par3, int par4, int par5, float par6, float par7, float par8, int par9)
    089        {
    090            byte var10 = 0;
    091
    092            if (par5 == 2 && par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST, true))
    093            {
    094                var10 = 2;
    095            }
    096
    097            if (par5 == 3 && par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST, true))
    098            {
    099                var10 = 0;
    100            }
    101
    102            if (par5 == 4 && par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH, true))
    103            {
    104                var10 = 1;
    105            }
    106
    107            if (par5 == 5 && par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH, true))
    108            {
    109                var10 = 3;
    110            }
    111
    112            return var10;
    113        }
    114
    115        public void func_85105_g(World par1World, int par2, int par3, int par4, int par5)
    116        {
    117            this.func_72143_a(par1World, par2, par3, par4, this.blockID, par5, false, -1, 0);
    118        }
    119
    120        /**
    121         * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
    122         * their own) Args: x, y, z, neighbor blockID
    123         */
    124        public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
    125        {
    126            if (par5 != this.blockID)
    127            {
    128                if (this.func_72144_l(par1World, par2, par3, par4))
    129                {
    130                    int var6 = par1World.getBlockMetadata(par2, par3, par4);
    131                    int var7 = var6 & 3;
    132                    boolean var8 = false;
    133
    134                    if (!par1World.isBlockSolidOnSide(par2 - 1, par3, par4, SOUTH) && var7 == 3)
    135                    {
    136                        var8 = true;
    137                    }
    138
    139                    if (!par1World.isBlockSolidOnSide(par2 + 1, par3, par4, NORTH) && var7 == 1)
    140                    {
    141                        var8 = true;
    142                    }
    143
    144                    if (!par1World.isBlockSolidOnSide(par2, par3, par4 - 1, EAST) && var7 == 0)
    145                    {
    146                        var8 = true;
    147                    }
    148
    149                    if (!par1World.isBlockSolidOnSide(par2, par3, par4 + 1, WEST) && var7 == 2)
    150                    {
    151                        var8 = true;
    152                    }
    153
    154                    if (var8)
    155                    {
    156                        this.dropBlockAsItem(par1World, par2, par3, par4, var6, 0);
    157                        par1World.setBlockWithNotify(par2, par3, par4, 0);
    158                    }
    159                }
    160            }
    161        }
    162
    163        public void func_72143_a(World par1World, int par2, int par3, int par4, int par5, int par6, boolean par7, int par8, int par9)
    164        {
    165            int var10 = par6 & 3;
    166            boolean var11 = (par6 & 4) == 4;
    167            boolean var12 = (par6 & 8) == 8;
    168            boolean var13 = par5 == Block.tripWireSource.blockID;
    169            boolean var14 = false;
    170            boolean var15 = !par1World.isBlockSolidOnSide(par2, par3 - 1, par4, UP);
    171            int var16 = Direction.offsetX[var10];
    172            int var17 = Direction.offsetZ[var10];
    173            int var18 = 0;
    174            int[] var19 = new int[42];
    175            int var21;
    176            int var20;
    177            int var23;
    178            int var22;
    179            int var24;
    180
    181            for (var20 = 1; var20 < 42; ++var20)
    182            {
    183                var21 = par2 + var16 * var20;
    184                var22 = par4 + var17 * var20;
    185                var23 = par1World.getBlockId(var21, par3, var22);
    186
    187                if (var23 == Block.tripWireSource.blockID)
    188                {
    189                    var24 = par1World.getBlockMetadata(var21, par3, var22);
    190
    191                    if ((var24 & 3) == Direction.footInvisibleFaceRemap[var10])
    192                    {
    193                        var18 = var20;
    194                    }
    195
    196                    break;
    197                }
    198
    199                if (var23 != Block.tripWire.blockID && var20 != par8)
    200                {
    201                    var19[var20] = -1;
    202                    var13 = false;
    203                }
    204                else
    205                {
    206                    var24 = var20 == par8 ? par9 : par1World.getBlockMetadata(var21, par3, var22);
    207                    boolean var25 = (var24 & 8) != 8;
    208                    boolean var26 = (var24 & 1) == 1;
    209                    boolean var27 = (var24 & 2) == 2;
    210                    var13 &= var27 == var15;
    211                    var14 |= var25 && var26;
    212                    var19[var20] = var24;
    213
    214                    if (var20 == par8)
    215                    {
    216                        par1World.scheduleBlockUpdate(par2, par3, par4, par5, this.tickRate());
    217                        var13 &= var25;
    218                    }
    219                }
    220            }
    221
    222            var13 &= var18 > 1;
    223            var14 &= var13;
    224            var20 = (var13 ? 4 : 0) | (var14 ? 8 : 0);
    225            par6 = var10 | var20;
    226
    227            if (var18 > 0)
    228            {
    229                var21 = par2 + var16 * var18;
    230                var22 = par4 + var17 * var18;
    231                var23 = Direction.footInvisibleFaceRemap[var10];
    232                par1World.setBlockMetadataWithNotify(var21, par3, var22, var23 | var20);
    233                this.notifyNeighborOfChange(par1World, var21, par3, var22, var23);
    234                this.playSoundEffect(par1World, var21, par3, var22, var13, var14, var11, var12);
    235            }
    236
    237            this.playSoundEffect(par1World, par2, par3, par4, var13, var14, var11, var12);
    238
    239            if (par5 > 0)
    240            {
    241                par1World.setBlockMetadataWithNotify(par2, par3, par4, par6);
    242
    243                if (par7)
    244                {
    245                    this.notifyNeighborOfChange(par1World, par2, par3, par4, var10);
    246                }
    247            }
    248
    249            if (var11 != var13)
    250            {
    251                for (var21 = 1; var21 < var18; ++var21)
    252                {
    253                    var22 = par2 + var16 * var21;
    254                    var23 = par4 + var17 * var21;
    255                    var24 = var19[var21];
    256
    257                    if (var24 >= 0)
    258                    {
    259                        if (var13)
    260                        {
    261                            var24 |= 4;
    262                        }
    263                        else
    264                        {
    265                            var24 &= -5;
    266                        }
    267
    268                        par1World.setBlockMetadataWithNotify(var22, par3, var23, var24);
    269                    }
    270                }
    271            }
    272        }
    273
    274        /**
    275         * Ticks the block if it's been scheduled
    276         */
    277        public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
    278        {
    279            this.func_72143_a(par1World, par2, par3, par4, this.blockID, par1World.getBlockMetadata(par2, par3, par4), true, -1, 0);
    280        }
    281
    282        /**
    283         * only of the conditions are right
    284         */
    285        private void playSoundEffect(World par1World, int par2, int par3, int par4, boolean par5, boolean par6, boolean par7, boolean par8)
    286        {
    287            if (par6 && !par8)
    288            {
    289                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.6F);
    290            }
    291            else if (!par6 && par8)
    292            {
    293                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.5F);
    294            }
    295            else if (par5 && !par7)
    296            {
    297                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.click", 0.4F, 0.7F);
    298            }
    299            else if (!par5 && par7)
    300            {
    301                par1World.playSoundEffect((double)par2 + 0.5D, (double)par3 + 0.1D, (double)par4 + 0.5D, "random.bowhit", 0.4F, 1.2F / (par1World.rand.nextFloat() * 0.2F + 0.9F));
    302            }
    303        }
    304
    305        private void notifyNeighborOfChange(World par1World, int par2, int par3, int par4, int par5)
    306        {
    307            par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
    308
    309            if (par5 == 3)
    310            {
    311                par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
    312            }
    313            else if (par5 == 1)
    314            {
    315                par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
    316            }
    317            else if (par5 == 0)
    318            {
    319                par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
    320            }
    321            else if (par5 == 2)
    322            {
    323                par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
    324            }
    325        }
    326
    327        private boolean func_72144_l(World par1World, int par2, int par3, int par4)
    328        {
    329            if (!this.canPlaceBlockAt(par1World, par2, par3, par4))
    330            {
    331                this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
    332                par1World.setBlockWithNotify(par2, par3, par4, 0);
    333                return false;
    334            }
    335            else
    336            {
    337                return true;
    338            }
    339        }
    340
    341        /**
    342         * Updates the blocks bounds based on its current state. Args: world, x, y, z
    343         */
    344        public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
    345        {
    346            int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 3;
    347            float var6 = 0.1875F;
    348
    349            if (var5 == 3)
    350            {
    351                this.setBlockBounds(0.0F, 0.2F, 0.5F - var6, var6 * 2.0F, 0.8F, 0.5F + var6);
    352            }
    353            else if (var5 == 1)
    354            {
    355                this.setBlockBounds(1.0F - var6 * 2.0F, 0.2F, 0.5F - var6, 1.0F, 0.8F, 0.5F + var6);
    356            }
    357            else if (var5 == 0)
    358            {
    359                this.setBlockBounds(0.5F - var6, 0.2F, 0.0F, 0.5F + var6, 0.8F, var6 * 2.0F);
    360            }
    361            else if (var5 == 2)
    362            {
    363                this.setBlockBounds(0.5F - var6, 0.2F, 1.0F - var6 * 2.0F, 0.5F + var6, 0.8F, 1.0F);
    364            }
    365        }
    366
    367        /**
    368         * ejects contained items into the world, and notifies neighbours of an update, as appropriate
    369         */
    370        public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
    371        {
    372            boolean var7 = (par6 & 4) == 4;
    373            boolean var8 = (par6 & 8) == 8;
    374
    375            if (var7 || var8)
    376            {
    377                this.func_72143_a(par1World, par2, par3, par4, 0, par6, false, -1, 0);
    378            }
    379
    380            if (var8)
    381            {
    382                par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
    383                int var9 = par6 & 3;
    384
    385                if (var9 == 3)
    386                {
    387                    par1World.notifyBlocksOfNeighborChange(par2 - 1, par3, par4, this.blockID);
    388                }
    389                else if (var9 == 1)
    390                {
    391                    par1World.notifyBlocksOfNeighborChange(par2 + 1, par3, par4, this.blockID);
    392                }
    393                else if (var9 == 0)
    394                {
    395                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 - 1, this.blockID);
    396                }
    397                else if (var9 == 2)
    398                {
    399                    par1World.notifyBlocksOfNeighborChange(par2, par3, par4 + 1, this.blockID);
    400                }
    401            }
    402
    403            super.breakBlock(par1World, par2, par3, par4, par5, par6);
    404        }
    405
    406        /**
    407         * Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube
    408         * returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X,
    409         * Y, Z, side
    410         */
    411        public boolean isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    412        {
    413            return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 8;
    414        }
    415
    416        /**
    417         * Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z,
    418         * side
    419         */
    420        public boolean isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    421        {
    422            int var6 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
    423
    424            if ((var6 & 8) != 8)
    425            {
    426                return false;
    427            }
    428            else
    429            {
    430                int var7 = var6 & 3;
    431                return var7 == 2 && par5 == 2 ? true : (var7 == 0 && par5 == 3 ? true : (var7 == 1 && par5 == 4 ? true : var7 == 3 && par5 == 5));
    432            }
    433        }
    434
    435        /**
    436         * Can this block provide power. Only wire currently seems to have this change based on its state.
    437         */
    438        public boolean canProvidePower()
    439        {
    440            return true;
    441        }
    442    }