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.ArrayList;
006    import java.util.HashMap;
007    import java.util.List;
008    import java.util.Map;
009    
010    public class MapData extends WorldSavedData
011    {
012        public int xCenter;
013        public int zCenter;
014        public byte dimension;
015        public byte scale;
016    
017        /** colours */
018        public byte[] colors = new byte[16384];
019    
020        /**
021         * Incremented each update of the map item, used for the patchy updating map effect and the spinning player icons
022         * while in the End and Nether.
023         */
024        public int randomEffect;
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 List playersVisibleOnMap = new ArrayList();
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            this.dimension = par1NBTTagCompound.getByte("dimension");
048            this.xCenter = par1NBTTagCompound.getInteger("xCenter");
049            this.zCenter = par1NBTTagCompound.getInteger("zCenter");
050            this.scale = par1NBTTagCompound.getByte("scale");
051    
052            if (this.scale < 0)
053            {
054                this.scale = 0;
055            }
056    
057            if (this.scale > 4)
058            {
059                this.scale = 4;
060            }
061    
062            short var2 = par1NBTTagCompound.getShort("width");
063            short var3 = par1NBTTagCompound.getShort("height");
064    
065            if (var2 == 128 && var3 == 128)
066            {
067                this.colors = par1NBTTagCompound.getByteArray("colors");
068            }
069            else
070            {
071                byte[] var4 = par1NBTTagCompound.getByteArray("colors");
072                this.colors = new byte[16384];
073                int var5 = (128 - var2) / 2;
074                int var6 = (128 - var3) / 2;
075    
076                for (int var7 = 0; var7 < var3; ++var7)
077                {
078                    int var8 = var7 + var6;
079    
080                    if (var8 >= 0 || var8 < 128)
081                    {
082                        for (int var9 = 0; var9 < var2; ++var9)
083                        {
084                            int var10 = var9 + var5;
085    
086                            if (var10 >= 0 || var10 < 128)
087                            {
088                                this.colors[var10 + var8 * 128] = var4[var9 + var7 * var2];
089                            }
090                        }
091                    }
092                }
093            }
094        }
095    
096        /**
097         * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities
098         */
099        public void writeToNBT(NBTTagCompound par1NBTTagCompound)
100        {
101            par1NBTTagCompound.setByte("dimension", this.dimension);
102            par1NBTTagCompound.setInteger("xCenter", this.xCenter);
103            par1NBTTagCompound.setInteger("zCenter", this.zCenter);
104            par1NBTTagCompound.setByte("scale", this.scale);
105            par1NBTTagCompound.setShort("width", (short)128);
106            par1NBTTagCompound.setShort("height", (short)128);
107            par1NBTTagCompound.setByteArray("colors", this.colors);
108        }
109    
110        /**
111         * Adds the player passed to the list of visible players and checks to see which players are visible
112         */
113        public void updateVisiblePlayers(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack)
114        {
115            if (!this.playersHashMap.containsKey(par1EntityPlayer))
116            {
117                MapInfo var3 = new MapInfo(this, par1EntityPlayer);
118                this.playersHashMap.put(par1EntityPlayer, var3);
119                this.playersArrayList.add(var3);
120            }
121    
122            this.playersVisibleOnMap.clear();
123    
124            for (int var14 = 0; var14 < this.playersArrayList.size(); ++var14)
125            {
126                MapInfo var4 = (MapInfo)this.playersArrayList.get(var14);
127    
128                if (!var4.entityplayerObj.isDead && var4.entityplayerObj.inventory.hasItemStack(par2ItemStack))
129                {
130                    float var5 = (float)(var4.entityplayerObj.posX - (double)this.xCenter) / (float)(1 << this.scale);
131                    float var6 = (float)(var4.entityplayerObj.posZ - (double)this.zCenter) / (float)(1 << this.scale);
132                    byte var7 = 64;
133                    byte var8 = 64;
134    
135                    if (var5 >= (float)(-var7) && var6 >= (float)(-var8) && var5 <= (float)var7 && var6 <= (float)var8)
136                    {
137                        byte var9 = 0;
138                        byte var10 = (byte)((int)((double)(var5 * 2.0F) + 0.5D));
139                        byte var11 = (byte)((int)((double)(var6 * 2.0F) + 0.5D));
140                        byte var12 = (byte)((int)((double)var4.entityplayerObj.rotationYaw * 16.0D / 360.0D));
141    
142                        if (this.dimension < 0)
143                        {
144                            int var13 = this.randomEffect / 10;
145                            var12 = (byte)(var13 * var13 * 34187121 + var13 * 121 >> 15 & 15);
146                        }
147    
148                        if (var4.entityplayerObj.dimension == this.dimension)
149                        {
150                            this.playersVisibleOnMap.add(new MapCoord(this, var9, var10, var11, var12));
151                        }
152                    }
153                }
154                else
155                {
156                    this.playersHashMap.remove(var4.entityplayerObj);
157                    this.playersArrayList.remove(var4);
158                }
159            }
160        }
161    
162        public byte[] func_76193_a(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
163        {
164            MapInfo var4 = (MapInfo)this.playersHashMap.get(par3EntityPlayer);
165            return var4 == null ? null : var4.getPlayersOnMap(par1ItemStack);
166        }
167    
168        public void func_76194_a(int par1, int par2, int par3)
169        {
170            super.markDirty();
171    
172            for (int var4 = 0; var4 < this.playersArrayList.size(); ++var4)
173            {
174                MapInfo var5 = (MapInfo)this.playersArrayList.get(var4);
175    
176                if (var5.field_76209_b[par1] < 0 || var5.field_76209_b[par1] > par2)
177                {
178                    var5.field_76209_b[par1] = par2;
179                }
180    
181                if (var5.field_76210_c[par1] < 0 || var5.field_76210_c[par1] < par3)
182                {
183                    var5.field_76210_c[par1] = par3;
184                }
185            }
186        }
187    
188        @SideOnly(Side.CLIENT)
189    
190        /**
191         * Updates the client's map with information from other players in MP
192         */
193        public void updateMPMapData(byte[] par1ArrayOfByte)
194        {
195            int var2;
196    
197            if (par1ArrayOfByte[0] == 0)
198            {
199                var2 = par1ArrayOfByte[1] & 255;
200                int var3 = par1ArrayOfByte[2] & 255;
201    
202                for (int var4 = 0; var4 < par1ArrayOfByte.length - 3; ++var4)
203                {
204                    this.colors[(var4 + var3) * 128 + var2] = par1ArrayOfByte[var4 + 3];
205                }
206    
207                this.markDirty();
208            }
209            else if (par1ArrayOfByte[0] == 1)
210            {
211                this.playersVisibleOnMap.clear();
212    
213                for (var2 = 0; var2 < (par1ArrayOfByte.length - 1) / 3; ++var2)
214                {
215                    byte var7 = (byte)(par1ArrayOfByte[var2 * 3 + 1] % 16);
216                    byte var8 = par1ArrayOfByte[var2 * 3 + 2];
217                    byte var5 = par1ArrayOfByte[var2 * 3 + 3];
218                    byte var6 = (byte)(par1ArrayOfByte[var2 * 3 + 1] / 16);
219                    this.playersVisibleOnMap.add(new MapCoord(this, var7, var8, var5, var6));
220                }
221            }
222        }
223    }