    001    package net.minecraft.item;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.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).func_76193_a(par1ItemStack, par2World, par3EntityPlayer);
    308            return var4 == null ? null : new Packet131MapData((short)Item.map.shiftedIndex, (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    }