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 }