    001package net.minecraft.item;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.List;
    006import net.minecraft.block.Block;
    007import net.minecraft.block.material.MapColor;
    008import net.minecraft.entity.Entity;
    009import net.minecraft.entity.player.EntityPlayer;
    010import net.minecraft.network.packet.Packet;
    011import net.minecraft.network.packet.Packet131MapData;
    012import net.minecraft.util.MathHelper;
    013import net.minecraft.world.World;
    014import net.minecraft.world.chunk.Chunk;
    015import net.minecraft.world.storage.MapData;
    016import net.minecraft.world.storage.MapInfo;
    017
    018public 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}