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