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