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