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.Entity;
008 import net.minecraft.item.ItemMonsterPlacer;
009 import net.minecraft.util.AxisAlignedBB;
010 import net.minecraft.world.IBlockAccess;
011 import net.minecraft.world.World;
012
013 public class BlockPortal extends BlockBreakable
014 {
015 public BlockPortal(int par1, int par2)
016 {
017 super(par1, par2, Material.portal, false);
018 this.setTickRandomly(true);
019 }
020
021 /**
022 * Ticks the block if it's been scheduled
023 */
024 public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
025 {
026 super.updateTick(par1World, par2, par3, par4, par5Random);
027
028 if (par1World.provider.isSurfaceWorld() && par5Random.nextInt(2000) < par1World.difficultySetting)
029 {
030 int var6;
031
032 for (var6 = par3; !par1World.doesBlockHaveSolidTopSurface(par2, var6, par4) && var6 > 0; --var6)
033 {
034 ;
035 }
036
037 if (var6 > 0 && !par1World.isBlockNormalCube(par2, var6 + 1, par4))
038 {
039 Entity var7 = ItemMonsterPlacer.spawnCreature(par1World, 57, (double)par2 + 0.5D, (double)var6 + 1.1D, (double)par4 + 0.5D);
040
041 if (var7 != null)
042 {
043 var7.timeUntilPortal = var7.getPortalCooldown();
044 }
045 }
046 }
047 }
048
049 /**
050 * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
051 * cleared to be reused)
052 */
053 public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
054 {
055 return null;
056 }
057
058 /**
059 * Updates the blocks bounds based on its current state. Args: world, x, y, z
060 */
061 public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
062 {
063 float var5;
064 float var6;
065
066 if (par1IBlockAccess.getBlockId(par2 - 1, par3, par4) != this.blockID && par1IBlockAccess.getBlockId(par2 + 1, par3, par4) != this.blockID)
067 {
068 var5 = 0.125F;
069 var6 = 0.5F;
070 this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6);
071 }
072 else
073 {
074 var5 = 0.5F;
075 var6 = 0.125F;
076 this.setBlockBounds(0.5F - var5, 0.0F, 0.5F - var6, 0.5F + var5, 1.0F, 0.5F + var6);
077 }
078 }
079
080 /**
081 * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
082 * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
083 */
084 public boolean isOpaqueCube()
085 {
086 return false;
087 }
088
089 /**
090 * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
091 */
092 public boolean renderAsNormalBlock()
093 {
094 return false;
095 }
096
097 /**
098 * Checks to see if this location is valid to create a portal and will return True if it does. Args: world, x, y, z
099 */
100 public boolean tryToCreatePortal(World par1World, int par2, int par3, int par4)
101 {
102 byte var5 = 0;
103 byte var6 = 0;
104
105 if (par1World.getBlockId(par2 - 1, par3, par4) == Block.obsidian.blockID || par1World.getBlockId(par2 + 1, par3, par4) == Block.obsidian.blockID)
106 {
107 var5 = 1;
108 }
109
110 if (par1World.getBlockId(par2, par3, par4 - 1) == Block.obsidian.blockID || par1World.getBlockId(par2, par3, par4 + 1) == Block.obsidian.blockID)
111 {
112 var6 = 1;
113 }
114
115 if (var5 == var6)
116 {
117 return false;
118 }
119 else
120 {
121 if (par1World.getBlockId(par2 - var5, par3, par4 - var6) == 0)
122 {
123 par2 -= var5;
124 par4 -= var6;
125 }
126
127 int var7;
128 int var8;
129
130 for (var7 = -1; var7 <= 2; ++var7)
131 {
132 for (var8 = -1; var8 <= 3; ++var8)
133 {
134 boolean var9 = var7 == -1 || var7 == 2 || var8 == -1 || var8 == 3;
135
136 if (var7 != -1 && var7 != 2 || var8 != -1 && var8 != 3)
137 {
138 int var10 = par1World.getBlockId(par2 + var5 * var7, par3 + var8, par4 + var6 * var7);
139
140 if (var9)
141 {
142 if (var10 != Block.obsidian.blockID)
143 {
144 return false;
145 }
146 }
147 else if (var10 != 0 && var10 != Block.fire.blockID)
148 {
149 return false;
150 }
151 }
152 }
153 }
154
155 par1World.editingBlocks = true;
156
157 for (var7 = 0; var7 < 2; ++var7)
158 {
159 for (var8 = 0; var8 < 3; ++var8)
160 {
161 par1World.setBlockWithNotify(par2 + var5 * var7, par3 + var8, par4 + var6 * var7, Block.portal.blockID);
162 }
163 }
164
165 par1World.editingBlocks = false;
166 return true;
167 }
168 }
169
170 /**
171 * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
172 * their own) Args: x, y, z, neighbor blockID
173 */
174 public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
175 {
176 byte var6 = 0;
177 byte var7 = 1;
178
179 if (par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID)
180 {
181 var6 = 1;
182 var7 = 0;
183 }
184
185 int var8;
186
187 for (var8 = par3; par1World.getBlockId(par2, var8 - 1, par4) == this.blockID; --var8)
188 {
189 ;
190 }
191
192 if (par1World.getBlockId(par2, var8 - 1, par4) != Block.obsidian.blockID)
193 {
194 par1World.setBlockWithNotify(par2, par3, par4, 0);
195 }
196 else
197 {
198 int var9;
199
200 for (var9 = 1; var9 < 4 && par1World.getBlockId(par2, var8 + var9, par4) == this.blockID; ++var9)
201 {
202 ;
203 }
204
205 if (var9 == 3 && par1World.getBlockId(par2, var8 + var9, par4) == Block.obsidian.blockID)
206 {
207 boolean var10 = par1World.getBlockId(par2 - 1, par3, par4) == this.blockID || par1World.getBlockId(par2 + 1, par3, par4) == this.blockID;
208 boolean var11 = par1World.getBlockId(par2, par3, par4 - 1) == this.blockID || par1World.getBlockId(par2, par3, par4 + 1) == this.blockID;
209
210 if (var10 && var11)
211 {
212 par1World.setBlockWithNotify(par2, par3, par4, 0);
213 }
214 else
215 {
216 if ((par1World.getBlockId(par2 + var6, par3, par4 + var7) != Block.obsidian.blockID || par1World.getBlockId(par2 - var6, par3, par4 - var7) != this.blockID) && (par1World.getBlockId(par2 - var6, par3, par4 - var7) != Block.obsidian.blockID || par1World.getBlockId(par2 + var6, par3, par4 + var7) != this.blockID))
217 {
218 par1World.setBlockWithNotify(par2, par3, par4, 0);
219 }
220 }
221 }
222 else
223 {
224 par1World.setBlockWithNotify(par2, par3, par4, 0);
225 }
226 }
227 }
228
229 @SideOnly(Side.CLIENT)
230
231 /**
232 * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
233 * coordinates. Args: blockAccess, x, y, z, side
234 */
235 public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
236 {
237 if (par1IBlockAccess.getBlockId(par2, par3, par4) == this.blockID)
238 {
239 return false;
240 }
241 else
242 {
243 boolean var6 = par1IBlockAccess.getBlockId(par2 - 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 - 2, par3, par4) != this.blockID;
244 boolean var7 = par1IBlockAccess.getBlockId(par2 + 1, par3, par4) == this.blockID && par1IBlockAccess.getBlockId(par2 + 2, par3, par4) != this.blockID;
245 boolean var8 = par1IBlockAccess.getBlockId(par2, par3, par4 - 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 - 2) != this.blockID;
246 boolean var9 = par1IBlockAccess.getBlockId(par2, par3, par4 + 1) == this.blockID && par1IBlockAccess.getBlockId(par2, par3, par4 + 2) != this.blockID;
247 boolean var10 = var6 || var7;
248 boolean var11 = var8 || var9;
249 return var10 && par5 == 4 ? true : (var10 && par5 == 5 ? true : (var11 && par5 == 2 ? true : var11 && par5 == 3));
250 }
251 }
252
253 /**
254 * Returns the quantity of items to drop on block destruction.
255 */
256 public int quantityDropped(Random par1Random)
257 {
258 return 0;
259 }
260
261 /**
262 * Triggered whenever an entity collides with this block (enters into the block). Args: world, x, y, z, entity
263 */
264 public void onEntityCollidedWithBlock(World par1World, int par2, int par3, int par4, Entity par5Entity)
265 {
266 if (par5Entity.ridingEntity == null && par5Entity.riddenByEntity == null)
267 {
268 par5Entity.setInPortal();
269 }
270 }
271
272 @SideOnly(Side.CLIENT)
273
274 /**
275 * Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
276 */
277 public int getRenderBlockPass()
278 {
279 return 1;
280 }
281
282 @SideOnly(Side.CLIENT)
283
284 /**
285 * A randomly called display update to be able to add particles or other items for display
286 */
287 public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
288 {
289 if (par5Random.nextInt(100) == 0)
290 {
291 par1World.playSound((double)par2 + 0.5D, (double)par3 + 0.5D, (double)par4 + 0.5D, "portal.portal", 0.5F, par5Random.nextFloat() * 0.4F + 0.8F, false);
292 }
293
294 for (int var6 = 0; var6 < 4; ++var6)
295 {
296 double var7 = (double)((float)par2 + par5Random.nextFloat());
297 double var9 = (double)((float)par3 + par5Random.nextFloat());
298 double var11 = (double)((float)par4 + par5Random.nextFloat());
299 double var13 = 0.0D;
300 double var15 = 0.0D;
301 double var17 = 0.0D;
302 int var19 = par5Random.nextInt(2) * 2 - 1;
303 var13 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
304 var15 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
305 var17 = ((double)par5Random.nextFloat() - 0.5D) * 0.5D;
306
307 if (par1World.getBlockId(par2 - 1, par3, par4) != this.blockID && par1World.getBlockId(par2 + 1, par3, par4) != this.blockID)
308 {
309 var7 = (double)par2 + 0.5D + 0.25D * (double)var19;
310 var13 = (double)(par5Random.nextFloat() * 2.0F * (float)var19);
311 }
312 else
313 {
314 var11 = (double)par4 + 0.5D + 0.25D * (double)var19;
315 var17 = (double)(par5Random.nextFloat() * 2.0F * (float)var19);
316 }
317
318 par1World.spawnParticle("portal", var7, var9, var11, var13, var15, var17);
319 }
320 }
321
322 @SideOnly(Side.CLIENT)
323
324 /**
325 * only called by clickMiddleMouseButton , and passed to inventory.setCurrentItem (along with isCreative)
326 */
327 public int idPicked(World par1World, int par2, int par3, int par4)
328 {
329 return 0;
330 }
331 }