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