001 package net.minecraft.world.storage;
002
003 import cpw.mods.fml.relauncher.Side;
004 import cpw.mods.fml.relauncher.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 /**
218 * Get byte array of packet data to send to players on map for updating map data
219 */
220 public byte[] getUpdatePacketData(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
221 {
222 MapInfo var4 = (MapInfo)this.playersHashMap.get(par3EntityPlayer);
223 return var4 == null ? null : var4.getPlayersOnMap(par1ItemStack);
224 }
225
226 /**
227 * Marks a vertical range of pixels as being modified so they will be resent to clients. Parameters: X, lowest Y,
228 * highest Y
229 */
230 public void setColumnDirty(int par1, int par2, int par3)
231 {
232 super.markDirty();
233
234 for (int var4 = 0; var4 < this.playersArrayList.size(); ++var4)
235 {
236 MapInfo var5 = (MapInfo)this.playersArrayList.get(var4);
237
238 if (var5.field_76209_b[par1] < 0 || var5.field_76209_b[par1] > par2)
239 {
240 var5.field_76209_b[par1] = par2;
241 }
242
243 if (var5.field_76210_c[par1] < 0 || var5.field_76210_c[par1] < par3)
244 {
245 var5.field_76210_c[par1] = par3;
246 }
247 }
248 }
249
250 @SideOnly(Side.CLIENT)
251
252 /**
253 * Updates the client's map with information from other players in MP
254 */
255 public void updateMPMapData(byte[] par1ArrayOfByte)
256 {
257 int var2;
258
259 if (par1ArrayOfByte[0] == 0)
260 {
261 var2 = par1ArrayOfByte[1] & 255;
262 int var3 = par1ArrayOfByte[2] & 255;
263
264 for (int var4 = 0; var4 < par1ArrayOfByte.length - 3; ++var4)
265 {
266 this.colors[(var4 + var3) * 128 + var2] = par1ArrayOfByte[var4 + 3];
267 }
268
269 this.markDirty();
270 }
271 else if (par1ArrayOfByte[0] == 1)
272 {
273 this.playersVisibleOnMap.clear();
274
275 for (var2 = 0; var2 < (par1ArrayOfByte.length - 1) / 3; ++var2)
276 {
277 byte var7 = (byte)(par1ArrayOfByte[var2 * 3 + 1] >> 4);
278 byte var8 = par1ArrayOfByte[var2 * 3 + 2];
279 byte var5 = par1ArrayOfByte[var2 * 3 + 3];
280 byte var6 = (byte)(par1ArrayOfByte[var2 * 3 + 1] & 15);
281 this.playersVisibleOnMap.put("icon-" + var2, new MapCoord(this, var7, var8, var5, var6));
282 }
283 }
284 else if (par1ArrayOfByte[0] == 2)
285 {
286 this.scale = par1ArrayOfByte[1];
287 }
288 }
289
290 public MapInfo func_82568_a(EntityPlayer par1EntityPlayer)
291 {
292 MapInfo var2 = (MapInfo)this.playersHashMap.get(par1EntityPlayer);
293
294 if (var2 == null)
295 {
296 var2 = new MapInfo(this, par1EntityPlayer);
297 this.playersHashMap.put(par1EntityPlayer, var2);
298 this.playersArrayList.add(var2);
299 }
300
301 return var2;
302 }
303 }