001 package net.minecraft.block; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import java.util.Random; 006 import net.minecraft.block.material.Material; 007 import net.minecraft.entity.item.EntityFallingSand; 008 import net.minecraft.entity.player.EntityPlayer; 009 import net.minecraft.world.IBlockAccess; 010 import net.minecraft.world.World; 011 012 public class BlockDragonEgg extends Block 013 { 014 public BlockDragonEgg(int par1, int par2) 015 { 016 super(par1, par2, Material.dragonEgg); 017 this.setBlockBounds(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); 018 } 019 020 /** 021 * Called whenever the block is added into the world. Args: world, x, y, z 022 */ 023 public void onBlockAdded(World par1World, int par2, int par3, int par4) 024 { 025 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 026 } 027 028 /** 029 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are 030 * their own) Args: x, y, z, neighbor blockID 031 */ 032 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5) 033 { 034 par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate()); 035 } 036 037 /** 038 * Ticks the block if it's been scheduled 039 */ 040 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) 041 { 042 this.fallIfPossible(par1World, par2, par3, par4); 043 } 044 045 /** 046 * Checks if the dragon egg can fall down, and if so, makes it fall. 047 */ 048 private void fallIfPossible(World par1World, int par2, int par3, int par4) 049 { 050 if (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 >= 0) 051 { 052 byte var5 = 32; 053 054 if (!BlockSand.fallInstantly && par1World.checkChunksExist(par2 - var5, par3 - var5, par4 - var5, par2 + var5, par3 + var5, par4 + var5)) 055 { 056 EntityFallingSand var6 = new EntityFallingSand(par1World, (double)((float)par2 + 0.5F), (double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), this.blockID); 057 par1World.spawnEntityInWorld(var6); 058 } 059 else 060 { 061 par1World.setBlockWithNotify(par2, par3, par4, 0); 062 063 while (BlockSand.canFallBelow(par1World, par2, par3 - 1, par4) && par3 > 0) 064 { 065 --par3; 066 } 067 068 if (par3 > 0) 069 { 070 par1World.setBlockWithNotify(par2, par3, par4, this.blockID); 071 } 072 } 073 } 074 } 075 076 /** 077 * Called upon block activation (right click on the block.) 078 */ 079 public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) 080 { 081 this.teleportNearby(par1World, par2, par3, par4); 082 return true; 083 } 084 085 /** 086 * Called when the block is clicked by a player. Args: x, y, z, entityPlayer 087 */ 088 public void onBlockClicked(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) 089 { 090 this.teleportNearby(par1World, par2, par3, par4); 091 } 092 093 /** 094 * Teleports the dragon egg somewhere else in a 31x19x31 area centered on the egg. 095 */ 096 private void teleportNearby(World par1World, int par2, int par3, int par4) 097 { 098 if (par1World.getBlockId(par2, par3, par4) == this.blockID) 099 { 100 for (int var5 = 0; var5 < 1000; ++var5) 101 { 102 int var6 = par2 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); 103 int var7 = par3 + par1World.rand.nextInt(8) - par1World.rand.nextInt(8); 104 int var8 = par4 + par1World.rand.nextInt(16) - par1World.rand.nextInt(16); 105 106 if (par1World.getBlockId(var6, var7, var8) == 0) 107 { 108 if (!par1World.isRemote) 109 { 110 par1World.setBlockAndMetadataWithNotify(var6, var7, var8, this.blockID, par1World.getBlockMetadata(par2, par3, par4)); 111 par1World.setBlockWithNotify(par2, par3, par4, 0); 112 } 113 else 114 { 115 short var9 = 128; 116 117 for (int var10 = 0; var10 < var9; ++var10) 118 { 119 double var11 = par1World.rand.nextDouble(); 120 float var13 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; 121 float var14 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; 122 float var15 = (par1World.rand.nextFloat() - 0.5F) * 0.2F; 123 double var16 = (double)var6 + (double)(par2 - var6) * var11 + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; 124 double var18 = (double)var7 + (double)(par3 - var7) * var11 + par1World.rand.nextDouble() * 1.0D - 0.5D; 125 double var20 = (double)var8 + (double)(par4 - var8) * var11 + (par1World.rand.nextDouble() - 0.5D) * 1.0D + 0.5D; 126 par1World.spawnParticle("portal", var16, var18, var20, (double)var13, (double)var14, (double)var15); 127 } 128 } 129 130 return; 131 } 132 } 133 } 134 } 135 136 /** 137 * How many world ticks before ticking 138 */ 139 public int tickRate() 140 { 141 return 5; 142 } 143 144 /** 145 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two 146 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. 147 */ 148 public boolean isOpaqueCube() 149 { 150 return false; 151 } 152 153 /** 154 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) 155 */ 156 public boolean renderAsNormalBlock() 157 { 158 return false; 159 } 160 161 @SideOnly(Side.CLIENT) 162 163 /** 164 * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given 165 * coordinates. Args: blockAccess, x, y, z, side 166 */ 167 public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) 168 { 169 return true; 170 } 171 172 /** 173 * The type of render function that is called for this block 174 */ 175 public int getRenderType() 176 { 177 return 27; 178 } 179 180 @SideOnly(Side.CLIENT) 181 182 /** 183 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative) 184 */ 185 public int idPicked(World par1World, int par2, int par3, int par4) 186 { 187 return 0; 188 } 189 }