001 package net.minecraft.item; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import java.util.List; 006 import net.minecraft.block.Block; 007 import net.minecraft.block.material.MapColor; 008 import net.minecraft.entity.Entity; 009 import net.minecraft.entity.player.EntityPlayer; 010 import net.minecraft.network.packet.Packet; 011 import net.minecraft.network.packet.Packet131MapData; 012 import net.minecraft.util.MathHelper; 013 import net.minecraft.world.World; 014 import net.minecraft.world.chunk.Chunk; 015 import net.minecraft.world.storage.MapData; 016 import net.minecraft.world.storage.MapInfo; 017 018 public class ItemMap extends ItemMapBase 019 { 020 protected ItemMap(int par1) 021 { 022 super(par1); 023 this.setHasSubtypes(true); 024 } 025 026 @SideOnly(Side.CLIENT) 027 public static MapData getMPMapData(short par0, World par1World) 028 { 029 String var2 = "map_" + par0; 030 MapData var3 = (MapData)par1World.loadItemData(MapData.class, var2); 031 032 if (var3 == null) 033 { 034 var3 = new MapData(var2); 035 par1World.setItemData(var2, var3); 036 } 037 038 return var3; 039 } 040 041 public MapData getMapData(ItemStack par1ItemStack, World par2World) 042 { 043 String var3 = "map_" + par1ItemStack.getItemDamage(); 044 MapData var4 = (MapData)par2World.loadItemData(MapData.class, var3); 045 046 if (var4 == null && !par2World.isRemote) 047 { 048 par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); 049 var3 = "map_" + par1ItemStack.getItemDamage(); 050 var4 = new MapData(var3); 051 var4.scale = 3; 052 int var5 = 128 * (1 << var4.scale); 053 var4.xCenter = Math.round((float)par2World.getWorldInfo().getSpawnX() / (float)var5) * var5; 054 var4.zCenter = Math.round((float)(par2World.getWorldInfo().getSpawnZ() / var5)) * var5; 055 var4.dimension = par2World.provider.dimensionId; 056 var4.markDirty(); 057 par2World.setItemData(var3, var4); 058 } 059 060 return var4; 061 } 062 063 public void updateMapData(World par1World, Entity par2Entity, MapData par3MapData) 064 { 065 if (par1World.provider.dimensionId == par3MapData.dimension && par2Entity instanceof EntityPlayer) 066 { 067 short var4 = 128; 068 short var5 = 128; 069 int var6 = 1 << par3MapData.scale; 070 int var7 = par3MapData.xCenter; 071 int var8 = par3MapData.zCenter; 072 int var9 = MathHelper.floor_double(par2Entity.posX - (double)var7) / var6 + var4 / 2; 073 int var10 = MathHelper.floor_double(par2Entity.posZ - (double)var8) / var6 + var5 / 2; 074 int var11 = 128 / var6; 075 076 if (par1World.provider.hasNoSky) 077 { 078 var11 /= 2; 079 } 080 081 MapInfo var12 = par3MapData.func_82568_a((EntityPlayer)par2Entity); 082 ++var12.field_82569_d; 083 084 for (int var13 = var9 - var11 + 1; var13 < var9 + var11; ++var13) 085 { 086 if ((var13 & 15) == (var12.field_82569_d & 15)) 087 { 088 int var14 = 255; 089 int var15 = 0; 090 double var16 = 0.0D; 091 092 for (int var18 = var10 - var11 - 1; var18 < var10 + var11; ++var18) 093 { 094 if (var13 >= 0 && var18 >= -1 && var13 < var4 && var18 < var5) 095 { 096 int var19 = var13 - var9; 097 int var20 = var18 - var10; 098 boolean var21 = var19 * var19 + var20 * var20 > (var11 - 2) * (var11 - 2); 099 int var22 = (var7 / var6 + var13 - var4 / 2) * var6; 100 int var23 = (var8 / var6 + var18 - var5 / 2) * var6; 101 int[] var24 = new int[Block.blocksList.length]; 102 Chunk var25 = par1World.getChunkFromBlockCoords(var22, var23); 103 104 if (!var25.isEmpty()) 105 { 106 int var26 = var22 & 15; 107 int var27 = var23 & 15; 108 int var28 = 0; 109 double var29 = 0.0D; 110 int var31; 111 int var32; 112 int var33; 113 int var36; 114 115 if (par1World.provider.hasNoSky) 116 { 117 var31 = var22 + var23 * 231871; 118 var31 = var31 * var31 * 31287121 + var31 * 11; 119 120 if ((var31 >> 20 & 1) == 0) 121 { 122 var24[Block.dirt.blockID] += 10; 123 } 124 else 125 { 126 var24[Block.stone.blockID] += 10; 127 } 128 129 var29 = 100.0D; 130 } 131 else 132 { 133 for (var31 = 0; var31 < var6; ++var31) 134 { 135 for (var32 = 0; var32 < var6; ++var32) 136 { 137 var33 = var25.getHeightValue(var31 + var26, var32 + var27) + 1; 138 int var34 = 0; 139 140 if (var33 > 1) 141 { 142 boolean var35; 143 144 do 145 { 146 var35 = true; 147 var34 = var25.getBlockID(var31 + var26, var33 - 1, var32 + var27); 148 149 if (var34 == 0) 150 { 151 var35 = false; 152 } 153 else if (var33 > 0 && var34 > 0 && Block.blocksList[var34].blockMaterial.materialMapColor == MapColor.airColor) 154 { 155 var35 = false; 156 } 157 158 if (!var35) 159 { 160 --var33; 161 162 if (var33 <= 0) 163 { 164 break; 165 } 166 167 var34 = var25.getBlockID(var31 + var26, var33 - 1, var32 + var27); 168 } 169 } 170 while (var33 > 0 && !var35); 171 172 if (var33 > 0 && var34 != 0 && Block.blocksList[var34].blockMaterial.isLiquid()) 173 { 174 var36 = var33 - 1; 175 boolean var37 = false; 176 int var43; 177 178 do 179 { 180 var43 = var25.getBlockID(var31 + var26, var36--, var32 + var27); 181 ++var28; 182 } 183 while (var36 > 0 && var43 != 0 && Block.blocksList[var43].blockMaterial.isLiquid()); 184 } 185 } 186 187 var29 += (double)var33 / (double)(var6 * var6); 188 ++var24[var34]; 189 } 190 } 191 } 192 193 var28 /= var6 * var6; 194 var31 = 0; 195 var32 = 0; 196 197 for (var33 = 0; var33 < Block.blocksList.length; ++var33) 198 { 199 if (var24[var33] > var31) 200 { 201 var32 = var33; 202 var31 = var24[var33]; 203 } 204 } 205 206 double var40 = (var29 - var16) * 4.0D / (double)(var6 + 4) + ((double)(var13 + var18 & 1) - 0.5D) * 0.4D; 207 byte var39 = 1; 208 209 if (var40 > 0.6D) 210 { 211 var39 = 2; 212 } 213 214 if (var40 < -0.6D) 215 { 216 var39 = 0; 217 } 218 219 var36 = 0; 220 221 if (var32 > 0) 222 { 223 MapColor var42 = Block.blocksList[var32].blockMaterial.materialMapColor; 224 225 if (var42 == MapColor.waterColor) 226 { 227 var40 = (double)var28 * 0.1D + (double)(var13 + var18 & 1) * 0.2D; 228 var39 = 1; 229 230 if (var40 < 0.5D) 231 { 232 var39 = 2; 233 } 234 235 if (var40 > 0.9D) 236 { 237 var39 = 0; 238 } 239 } 240 241 var36 = var42.colorIndex; 242 } 243 244 var16 = var29; 245 246 if (var18 >= 0 && var19 * var19 + var20 * var20 < var11 * var11 && (!var21 || (var13 + var18 & 1) != 0)) 247 { 248 byte var41 = par3MapData.colors[var13 + var18 * var4]; 249 byte var38 = (byte)(var36 * 4 + var39); 250 251 if (var41 != var38) 252 { 253 if (var14 > var18) 254 { 255 var14 = var18; 256 } 257 258 if (var15 < var18) 259 { 260 var15 = var18; 261 } 262 263 par3MapData.colors[var13 + var18 * var4] = var38; 264 } 265 } 266 } 267 } 268 } 269 270 if (var14 <= var15) 271 { 272 par3MapData.setColumnDirty(var13, var14, var15); 273 } 274 } 275 } 276 } 277 } 278 279 /** 280 * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and 281 * update it's contents. 282 */ 283 public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) 284 { 285 if (!par2World.isRemote) 286 { 287 MapData var6 = this.getMapData(par1ItemStack, par2World); 288 289 if (par3Entity instanceof EntityPlayer) 290 { 291 EntityPlayer var7 = (EntityPlayer)par3Entity; 292 var6.updateVisiblePlayers(var7, par1ItemStack); 293 } 294 295 if (par5) 296 { 297 this.updateMapData(par2World, par3Entity, var6); 298 } 299 } 300 } 301 302 /** 303 * returns null if no update is to be sent 304 */ 305 public Packet createMapDataPacket(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) 306 { 307 byte[] var4 = this.getMapData(par1ItemStack, par2World).getUpdatePacketData(par1ItemStack, par2World, par3EntityPlayer); 308 return var4 == null ? null : new Packet131MapData((short)Item.map.itemID, (short)par1ItemStack.getItemDamage(), var4); 309 } 310 311 /** 312 * Called when item is crafted/smelted. Used only by maps so far. 313 */ 314 public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) 315 { 316 if (par1ItemStack.hasTagCompound() && par1ItemStack.getTagCompound().getBoolean("map_is_scaling")) 317 { 318 MapData var4 = Item.map.getMapData(par1ItemStack, par2World); 319 par1ItemStack.setItemDamage(par2World.getUniqueDataId("map")); 320 MapData var5 = new MapData("map_" + par1ItemStack.getItemDamage()); 321 var5.scale = (byte)(var4.scale + 1); 322 323 if (var5.scale > 4) 324 { 325 var5.scale = 4; 326 } 327 328 var5.xCenter = var4.xCenter; 329 var5.zCenter = var4.zCenter; 330 var5.dimension = var4.dimension; 331 var5.markDirty(); 332 par2World.setItemData("map_" + par1ItemStack.getItemDamage(), var5); 333 } 334 } 335 336 @SideOnly(Side.CLIENT) 337 338 /** 339 * allows items to add custom lines of information to the mouseover description 340 */ 341 public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) 342 { 343 MapData var5 = this.getMapData(par1ItemStack, par2EntityPlayer.worldObj); 344 345 if (par4) 346 { 347 if (var5 == null) 348 { 349 par3List.add("Unknown map"); 350 } 351 else 352 { 353 par3List.add("Scaling at 1:" + (1 << var5.scale)); 354 par3List.add("(Level " + var5.scale + "/" + 4 + ")"); 355 } 356 } 357 } 358 }