    001    package net.minecraft.world.storage;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.ArrayList;
    006    import java.util.HashMap;
    007    import java.util.LinkedHashMap;
    008    import java.util.List;
    009    import java.util.Map;
    010    import net.minecraft.entity.player.EntityPlayer;
    011    import net.minecraft.item.ItemStack;
    012    import net.minecraft.nbt.*;
    013    import net.minecraft.world.World;
    014    import net.minecraft.world.WorldSavedData;
    015
    016    public class MapData extends WorldSavedData
    017    {
    018        public int xCenter;
    019        public int zCenter;
    020        public int dimension;
    021        public byte scale;
    022
    023        /** colours */
    024        public byte[] colors = new byte[16384];
    025
    026        /**
    027         * Holds a reference to the MapInfo of the players who own a copy of the map
    028         */
    029        public List playersArrayList = new ArrayList();
    030
    031        /**
    032         * Holds a reference to the players who own a copy of the map and a reference to their MapInfo
    033         */
    034        private Map playersHashMap = new HashMap();
    035        public Map playersVisibleOnMap = new LinkedHashMap();
    036
    037        public MapData(String par1Str)
    038        {
    039            super(par1Str);
    040        }
    041
    042        /**
    043         * reads in data from the NBTTagCompound into this MapDataBase
    044         */
    045        public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    046        {
    047            NBTBase dimension = par1NBTTagCompound.getTag("dimension");
    048
    049            if (dimension instanceof NBTTagByte)
    050            {
    051                this.dimension = ((NBTTagByte)dimension).data;
    052            }
    053            else
    054            {
    055                this.dimension = ((NBTTagInt)dimension).data;
    056            }
    057
    058            this.xCenter = par1NBTTagCompound.getInteger("xCenter");
    059            this.zCenter = par1NBTTagCompound.getInteger("zCenter");
    060            this.scale = par1NBTTagCompound.getByte("scale");
    061
    062            if (this.scale < 0)
    063            {
    064                this.scale = 0;
    065            }
    066
    067            if (this.scale > 4)
    068            {
    069                this.scale = 4;
    070            }
    071
    072            short var2 = par1NBTTagCompound.getShort("width");
    073            short var3 = par1NBTTagCompound.getShort("height");
    074
    075            if (var2 == 128 && var3 == 128)
    076            {
    077                this.colors = par1NBTTagCompound.getByteArray("colors");
    078            }
    079            else
    080            {
    081                byte[] var4 = par1NBTTagCompound.getByteArray("colors");
    082                this.colors = new byte[16384];
    083                int var5 = (128 - var2) / 2;
    084                int var6 = (128 - var3) / 2;
    085
    086                for (int var7 = 0; var7 < var3; ++var7)
    087                {
    088                    int var8 = var7 + var6;
    089
    090                    if (var8 >= 0 || var8 < 128)
    091                    {
    092                        for (int var9 = 0; var9 < var2; ++var9)
    093                        {
    094                            int var10 = var9 + var5;
    095
    096                            if (var10 >= 0 || var10 < 128)
    097                            {
    098                                this.colors[var10 + var8 * 128] = var4[var9 + var7 * var2];
    099                            }
    100                        }
    101                    }
    102                }
    103            }
    104        }
    105
    106        /**
    107         * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities
    108         */
    109        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    110        {
    111            par1NBTTagCompound.setInteger("dimension", this.dimension);
    112            par1NBTTagCompound.setInteger("xCenter", this.xCenter);
    113            par1NBTTagCompound.setInteger("zCenter", this.zCenter);
    114            par1NBTTagCompound.setByte("scale", this.scale);
    115            par1NBTTagCompound.setShort("width", (short)128);
    116            par1NBTTagCompound.setShort("height", (short)128);
    117            par1NBTTagCompound.setByteArray("colors", this.colors);
    118        }
    119
    120        /**
    121         * Adds the player passed to the list of visible players and checks to see which players are visible
    122         */
    123        public void updateVisiblePlayers(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack)
    124        {
    125            if (!this.playersHashMap.containsKey(par1EntityPlayer))
    126            {
    127                MapInfo var3 = new MapInfo(this, par1EntityPlayer);
    128                this.playersHashMap.put(par1EntityPlayer, var3);
    129                this.playersArrayList.add(var3);
    130            }
    131
    132            if (!par1EntityPlayer.inventory.hasItemStack(par2ItemStack))
    133            {
    134                this.playersVisibleOnMap.remove(par1EntityPlayer.getCommandSenderName());
    135            }
    136
    137            for (int var5 = 0; var5 < this.playersArrayList.size(); ++var5)
    138            {
    139                MapInfo var4 = (MapInfo)this.playersArrayList.get(var5);
    140
    141                if (!var4.entityplayerObj.isDead && (var4.entityplayerObj.inventory.hasItemStack(par2ItemStack) || par2ItemStack.isOnItemFrame()))
    142                {
    143                    if (!par2ItemStack.isOnItemFrame() && var4.entityplayerObj.dimension == this.dimension)
    144                    {
    145                        this.func_82567_a(0, var4.entityplayerObj.worldObj, var4.entityplayerObj.getCommandSenderName(), var4.entityplayerObj.posX, var4.entityplayerObj.posZ, (double)var4.entityplayerObj.rotationYaw);
    146                    }
    147                }
    148                else
    149                {
    150                    this.playersHashMap.remove(var4.entityplayerObj);
    151                    this.playersArrayList.remove(var4);
    152                }
    153            }
    154
    155            if (par2ItemStack.isOnItemFrame())
    156            {
    157                this.func_82567_a(1, par1EntityPlayer.worldObj, "frame-" + par2ItemStack.getItemFrame().entityId, (double)par2ItemStack.getItemFrame().xPosition, (double)par2ItemStack.getItemFrame().zPosition, (double)(par2ItemStack.getItemFrame().hangingDirection * 90));
    158            }
    159        }
    160
    161        private void func_82567_a(int par1, World par2World, String par3Str, double par4, double par6, double par8)
    162        {
    163            int var10 = 1 << this.scale;
    164            float var11 = (float)(par4 - (double)this.xCenter) / (float)var10;
    165            float var12 = (float)(par6 - (double)this.zCenter) / (float)var10;
    166            byte var13 = (byte)((int)((double)(var11 * 2.0F) + 0.5D));
    167            byte var14 = (byte)((int)((double)(var12 * 2.0F) + 0.5D));
    168            byte var16 = 63;
    169            byte var15;
    170
    171            if (var11 >= (float)(-var16) && var12 >= (float)(-var16) && var11 <= (float)var16 && var12 <= (float)var16)
    172            {
    173                par8 += par8 < 0.0D ? -8.0D : 8.0D;
    174                var15 = (byte)((int)(par8 * 16.0D / 360.0D));
    175
    176                if (par2World.provider.shouldMapSpin(par3Str, par4, par6, par8))
    177                {
    178                    int var17 = (int)(par2World.getWorldInfo().getWorldTime() / 10L);
    179                    var15 = (byte)(var17 * var17 * 34187121 + var17 * 121 >> 15 & 15);
    180                }
    181            }
    182            else
    183            {
    184                if (Math.abs(var11) >= 320.0F || Math.abs(var12) >= 320.0F)
    185                {
    186                    this.playersVisibleOnMap.remove(par3Str);
    187                    return;
    188                }
    189
    190                par1 = 6;
    191                var15 = 0;
    192
    193                if (var11 <= (float)(-var16))
    194                {
    195                    var13 = (byte)((int)((double)(var16 * 2) + 2.5D));
    196                }
    197
    198                if (var12 <= (float)(-var16))
    199                {
    200                    var14 = (byte)((int)((double)(var16 * 2) + 2.5D));
    201                }
    202
    203                if (var11 >= (float)var16)
    204                {
    205                    var13 = (byte)(var16 * 2 + 1);
    206                }
    207
    208                if (var12 >= (float)var16)
    209                {
    210                    var14 = (byte)(var16 * 2 + 1);
    211                }
    212            }
    213
    214            this.playersVisibleOnMap.put(par3Str, new MapCoord(this, (byte)par1, var13, var14, var15));
    215        }
    216
    217        public byte[] func_76193_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
    218        {
    219            MapInfo var4 = (MapInfo)this.playersHashMap.get(par3EntityPlayer);
    220            return var4 == null ? null : var4.getPlayersOnMap(par1ItemStack);
    221        }
    222
    223        /**
    224         * Marks a vertical range of pixels as being modified so they will be resent to clients. Parameters: X, lowest Y,
    225         * highest Y
    226         */
    227        public void setColumnDirty(int par1, int par2, int par3)
    228        {
    229            super.markDirty();
    230
    231            for (int var4 = 0; var4 < this.playersArrayList.size(); ++var4)
    232            {
    233                MapInfo var5 = (MapInfo)this.playersArrayList.get(var4);
    234
    235                if (var5.field_76209_b[par1] < 0 || var5.field_76209_b[par1] > par2)
    236                {
    237                    var5.field_76209_b[par1] = par2;
    238                }
    239
    240                if (var5.field_76210_c[par1] < 0 || var5.field_76210_c[par1] < par3)
    241                {
    242                    var5.field_76210_c[par1] = par3;
    243                }
    244            }
    245        }
    246
    247        @SideOnly(Side.CLIENT)
    248
    249        /**
    250         * Updates the client's map with information from other players in MP
    251         */
    252        public void updateMPMapData(byte[] par1ArrayOfByte)
    253        {
    254            int var2;
    255
    256            if (par1ArrayOfByte[0] == 0)
    257            {
    258                var2 = par1ArrayOfByte[1] & 255;
    259                int var3 = par1ArrayOfByte[2] & 255;
    260
    261                for (int var4 = 0; var4 < par1ArrayOfByte.length - 3; ++var4)
    262                {
    263                    this.colors[(var4 + var3) * 128 + var2] = par1ArrayOfByte[var4 + 3];
    264                }
    265
    266                this.markDirty();
    267            }
    268            else if (par1ArrayOfByte[0] == 1)
    269            {
    270                this.playersVisibleOnMap.clear();
    271
    272                for (var2 = 0; var2 < (par1ArrayOfByte.length - 1) / 3; ++var2)
    273                {
    274                    byte var7 = (byte)(par1ArrayOfByte[var2 * 3 + 1] >> 4);
    275                    byte var8 = par1ArrayOfByte[var2 * 3 + 2];
    276                    byte var5 = par1ArrayOfByte[var2 * 3 + 3];
    277                    byte var6 = (byte)(par1ArrayOfByte[var2 * 3 + 1] & 15);
    278                    this.playersVisibleOnMap.put("icon-" + var2, new MapCoord(this, var7, var8, var5, var6));
    279                }
    280            }
    281            else if (par1ArrayOfByte[0] == 2)
    282            {
    283                this.scale = par1ArrayOfByte[1];
    284            }
    285        }
    286
    287        public MapInfo func_82568_a(EntityPlayer par1EntityPlayer)
    288        {
    289            MapInfo var2 = (MapInfo)this.playersHashMap.get(par1EntityPlayer);
    290
    291            if (var2 == null)
    292            {
    293                var2 = new MapInfo(this, par1EntityPlayer);
    294                this.playersHashMap.put(par1EntityPlayer, var2);
    295                this.playersArrayList.add(var2);
    296            }
    297
    298            return var2;
    299        }
    300    }