001package net.minecraft.block; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import java.util.List; 006import java.util.Random; 007import net.minecraft.client.renderer.texture.IconRegister; 008import net.minecraft.command.IEntitySelector; 009import net.minecraft.entity.Entity; 010import net.minecraft.entity.item.EntityMinecart; 011import net.minecraft.inventory.Container; 012import net.minecraft.inventory.IInventory; 013import net.minecraft.util.AxisAlignedBB; 014import net.minecraft.util.Icon; 015import net.minecraft.world.IBlockAccess; 016import net.minecraft.world.World; 017 018public class BlockDetectorRail extends BlockRailBase 019{ 020 @SideOnly(Side.CLIENT) 021 private Icon[] field_100010_b; 022 023 public BlockDetectorRail(int par1) 024 { 025 super(par1, true); 026 this.setTickRandomly(true); 027 } 028 029 /** 030 * How many world ticks before ticking 031 */ 032 public int tickRate(World par1World) 033 { 034 return 20; 035 } 036 037 /** 038 * Can this block provide power. Only wire currently seems to have this change based on its state. 039 */ 040 public boolean canProvidePower() 041 { 042 return true; 043 } 044 045 /** 046 * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity 047 */ 048 public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity) 049 { 050 if (!par1World.isRemote) 051 { 052 int l = par1World.getBlockMetadata(par2, par3, par4); 053 054 if ((l & 8) == 0) 055 { 056 this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, l); 057 } 058 } 059 } 060 061 /** 062 * Ticks the block if it's been scheduled 063 */ 064 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 065 { 066 if (!par1World.isRemote) 067 { 068 int l = par1World.getBlockMetadata(par2, par3, par4); 069 070 if ((l & 8) != 0) 071 { 072 this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, l); 073 } 074 } 075 } 076 077 /** 078 * Returns true if the block is emitting indirect/weak redstone power on the specified side. If isBlockNormalCube 079 * returns true, standard redstone propagation rules will apply instead and this will not be called. Args: World, X, 080 * Y, Z, side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block. 081 */ 082 public int isProvidingWeakPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 083 { 084 return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) != 0 ? 15 : 0; 085 } 086 087 /** 088 * Returns true if the block is emitting direct/strong redstone power on the specified side. Args: World, X, Y, Z, 089 * side. Note that the side is reversed - eg it is 1 (up) when checking the bottom of the block. 090 */ 091 public int isProvidingStrongPower(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 092 { 093 return (par1IBlockAccess.getBlockMetadata(par2, par3, par4) & 8) == 0 ? 0 : (par5 == 1 ? 15 : 0); 094 } 095 096 /** 097 * Update the detector rail power state if a minecart enter, stays or leave the block. 098 */ 099 private void setStateIfMinecartInteractsWithRail(World par1World, int par2, int par3, int par4, int par5) 100 { 101 boolean flag = (par5 & 8) != 0; 102 boolean flag1 = false; 103 float f = 0.125F; 104 List list = par1World.getEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)((float)(par3 + 1) - f), (double)((float)(par4 + 1) - f))); 105 106 if (!list.isEmpty()) 107 { 108 flag1 = true; 109 } 110 111 if (flag1 && !flag) 112 { 113 par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 | 8, 3); 114 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 115 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 116 par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); 117 } 118 119 if (!flag1 && flag) 120 { 121 par1World.setBlockMetadataWithNotify(par2, par3, par4, par5 & 7, 3); 122 par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID); 123 par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, this.blockID); 124 par1World.markBlockRangeForRenderUpdate(par2, par3, par4, par2, par3, par4); 125 } 126 127 if (flag1) 128 { 129 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate(par1World)); 130 } 131 132 par1World.func_96440_m(par2, par3, par4, this.blockID); 133 } 134 135 /** 136 * Called whenever the block is added into the world. Args: world, x, y, z 137 */ 138 public void onBlockAdded(World par1World, int par2, int par3, int par4) 139 { 140 super.onBlockAdded(par1World, par2, par3, par4); 141 this.setStateIfMinecartInteractsWithRail(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4)); 142 } 143 144 public boolean func_96468_q_() 145 { 146 return true; 147 } 148 149 public int func_94328_b_(World par1World, int par2, int par3, int par4, int par5) 150 { 151 if ((par1World.getBlockMetadata(par2, par3, par4) & 8) > 0) 152 { 153 float f = 0.125F; 154 List list = par1World.selectEntitiesWithinAABB(EntityMinecart.class, AxisAlignedBB.getAABBPool().getAABB((double)((float)par2 + f), (double)par3, (double)((float)par4 + f), (double)((float)(par2 + 1) - f), (double)((float)(par3 + 1) - f), (double)((float)(par4 + 1) - f)), IEntitySelector.field_96566_b); 155 156 if (list.size() > 0) 157 { 158 return Container.func_94526_b((IInventory)list.get(0)); 159 } 160 } 161 162 return 0; 163 } 164 165 @SideOnly(Side.CLIENT) 166 public void func_94332_a(IconRegister par1IconRegister) 167 { 168 this.field_100010_b = new Icon[2]; 169 this.field_100010_b[0] = par1IconRegister.func_94245_a("detectorRail"); 170 this.field_100010_b[1] = par1IconRegister.func_94245_a("detectorRail_on"); 171 } 172 173 @SideOnly(Side.CLIENT) 174 175 /** 176 * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata 177 */ 178 public Icon getBlockTextureFromSideAndMetadata(int par1, int par2) 179 { 180 return (par2 & 8) != 0 ? this.field_100010_b[1] : this.field_100010_b[0]; 181 } 182}