aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Land
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Land')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs1998
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs156
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandObject.cs1854
3 files changed, 2004 insertions, 2004 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
index efc5234..9ac3cc3 100644
--- a/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandChannel.cs
@@ -1,1000 +1,1000 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using Axiom.Math; 30using Axiom.Math;
31using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36using OpenSim.Region.Physics.Manager; 36using OpenSim.Region.Physics.Manager;
37 37
38namespace OpenSim.Region.Environment.Modules.World.Land 38namespace OpenSim.Region.Environment.Modules.World.Land
39{ 39{
40 public class LandChannel : ILandChannel 40 public class LandChannel : ILandChannel
41 { 41 {
42 #region Constants 42 #region Constants
43 43
44 //Land types set with flags in ParcelOverlay. 44 //Land types set with flags in ParcelOverlay.
45 //Only one of these can be used. 45 //Only one of these can be used.
46 public const float BAN_LINE_SAFETY_HIEGHT = 100; 46 public const float BAN_LINE_SAFETY_HIEGHT = 100;
47 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000 47 public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte) 128; //Equals 10000000
48 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000 48 public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte) 64; //Equals 01000000
49 49
50 //RequestResults (I think these are right, they seem to work): 50 //RequestResults (I think these are right, they seem to work):
51 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land 51 public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land
52 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land 52 public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land
53 53
54 //ParcelSelectObjects 54 //ParcelSelectObjects
55 public const int LAND_SELECT_OBJECTS_GROUP = 4; 55 public const int LAND_SELECT_OBJECTS_GROUP = 4;
56 public const int LAND_SELECT_OBJECTS_OTHER = 8; 56 public const int LAND_SELECT_OBJECTS_OTHER = 8;
57 public const int LAND_SELECT_OBJECTS_OWNER = 2; 57 public const int LAND_SELECT_OBJECTS_OWNER = 2;
58 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101 58 public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte) 5; //Equals 00000101
59 public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100 59 public const byte LAND_TYPE_IS_FOR_SALE = (byte) 4; //Equals 00000100
60 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010 60 public const byte LAND_TYPE_OWNED_BY_GROUP = (byte) 2; //Equals 00000010
61 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001 61 public const byte LAND_TYPE_OWNED_BY_OTHER = (byte) 1; //Equals 00000001
62 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011 62 public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte) 3; //Equals 00000011
63 public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000 63 public const byte LAND_TYPE_PUBLIC = (byte) 0; //Equals 00000000
64 64
65 //These are other constants. Yay! 65 //These are other constants. Yay!
66 public const int START_LAND_LOCAL_ID = 1; 66 public const int START_LAND_LOCAL_ID = 1;
67 67
68 #endregion 68 #endregion
69 69
70 private int[,] landIDList = new int[64,64]; 70 private int[,] landIDList = new int[64,64];
71 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); 71 private Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>();
72 72
73 private bool landPrimCountTainted = false; 73 private bool landPrimCountTainted = false;
74 private int lastLandLocalID = START_LAND_LOCAL_ID - 1; 74 private int lastLandLocalID = START_LAND_LOCAL_ID - 1;
75 75
76 private bool m_allowedForcefulBans = true; 76 private bool m_allowedForcefulBans = true;
77 private Scene m_scene; 77 private Scene m_scene;
78 78
79 public LandChannel(Scene scene) 79 public LandChannel(Scene scene)
80 { 80 {
81 m_scene = scene; 81 m_scene = scene;
82 landIDList.Initialize(); 82 landIDList.Initialize();
83 } 83 }
84 84
85 #region Land Object From Storage Functions 85 #region Land Object From Storage Functions
86 86
87 public void IncomingLandObjectsFromStorage(List<LandData> data) 87 public void IncomingLandObjectsFromStorage(List<LandData> data)
88 { 88 {
89 for (int i = 0; i < data.Count; i++) 89 for (int i = 0; i < data.Count; i++)
90 { 90 {
91 //try 91 //try
92 //{ 92 //{
93 IncomingLandObjectFromStorage(data[i]); 93 IncomingLandObjectFromStorage(data[i]);
94 //} 94 //}
95 //catch (Exception ex) 95 //catch (Exception ex)
96 //{ 96 //{
97 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString()); 97 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString());
98 //throw ex; 98 //throw ex;
99 //} 99 //}
100 } 100 }
101 //foreach (LandData parcel in data) 101 //foreach (LandData parcel in data)
102 //{ 102 //{
103 // IncomingLandObjectFromStorage(parcel); 103 // IncomingLandObjectFromStorage(parcel);
104 //} 104 //}
105 } 105 }
106 106
107 public void IncomingLandObjectFromStorage(LandData data) 107 public void IncomingLandObjectFromStorage(LandData data)
108 { 108 {
109 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene); 109 ILandObject new_land = new LandObject(data.ownerID, data.isGroupOwned, m_scene);
110 new_land.landData = data.Copy(); 110 new_land.landData = data.Copy();
111 new_land.setLandBitmapFromByteArray(); 111 new_land.setLandBitmapFromByteArray();
112 addLandObject(new_land); 112 addLandObject(new_land);
113 } 113 }
114 114
115 public void NoLandDataFromStorage() 115 public void NoLandDataFromStorage()
116 { 116 {
117 resetSimLandObjects(); 117 resetSimLandObjects();
118 } 118 }
119 119
120 #endregion 120 #endregion
121 121
122 #region Parcel Add/Remove/Get/Create 122 #region Parcel Add/Remove/Get/Create
123 123
124 public void updateLandObject(int local_id, LandData newData) 124 public void updateLandObject(int local_id, LandData newData)
125 { 125 {
126 if (landList.ContainsKey(local_id)) 126 if (landList.ContainsKey(local_id))
127 { 127 {
128 landList[local_id].landData = newData.Copy(); 128 landList[local_id].landData = newData.Copy();
129 m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]); 129 m_scene.EventManager.TriggerLandObjectUpdated((uint) local_id, landList[local_id]);
130 } 130 }
131 } 131 }
132 132
133 /// <summary> 133 /// <summary>
134 /// Get the land object at the specified point 134 /// Get the land object at the specified point
135 /// </summary> 135 /// </summary>
136 /// <param name="x">Value between 0 - 256 on the x axis of the point</param> 136 /// <param name="x">Value between 0 - 256 on the x axis of the point</param>
137 /// <param name="y">Value between 0 - 256 on the y axis of the point</param> 137 /// <param name="y">Value between 0 - 256 on the y axis of the point</param>
138 /// <returns>Land object at the point supplied</returns> 138 /// <returns>Land object at the point supplied</returns>
139 public ILandObject getLandObject(float x_float, float y_float) 139 public ILandObject getLandObject(float x_float, float y_float)
140 { 140 {
141 int x; 141 int x;
142 int y; 142 int y;
143 143
144 try 144 try
145 { 145 {
146 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0))); 146 x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0)));
147 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0))); 147 y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0)));
148 } 148 }
149 catch (OverflowException) 149 catch (OverflowException)
150 { 150 {
151 return null; 151 return null;
152 } 152 }
153 153
154 if (x >= 64 || y >= 64 || x < 0 || y < 0) 154 if (x >= 64 || y >= 64 || x < 0 || y < 0)
155 { 155 {
156 return null; 156 return null;
157 } 157 }
158 else 158 else
159 { 159 {
160 return landList[landIDList[x, y]]; 160 return landList[landIDList[x, y]];
161 } 161 }
162 } 162 }
163 163
164 public ILandObject getLandObject(int x, int y) 164 public ILandObject getLandObject(int x, int y)
165 { 165 {
166 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0) 166 if (x >= Convert.ToInt32(Constants.RegionSize) || y >= Convert.ToInt32(Constants.RegionSize) || x < 0 || y < 0)
167 { 167 {
168 // These exceptions here will cause a lot of complaints from the users specifically because 168 // These exceptions here will cause a lot of complaints from the users specifically because
169 // they happen every time at border crossings 169 // they happen every time at border crossings
170 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 170 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
171 } 171 }
172 else 172 else
173 { 173 {
174 return landList[landIDList[x / 4, y / 4]]; 174 return landList[landIDList[x / 4, y / 4]];
175 } 175 }
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Creates a basic Parcel object without an owner (a zeroed key) 179 /// Creates a basic Parcel object without an owner (a zeroed key)
180 /// </summary> 180 /// </summary>
181 /// <returns></returns> 181 /// <returns></returns>
182 public ILandObject createBaseLand() 182 public ILandObject createBaseLand()
183 { 183 {
184 return new LandObject(LLUUID.Zero, false, m_scene); 184 return new LandObject(LLUUID.Zero, false, m_scene);
185 } 185 }
186 186
187 /// <summary> 187 /// <summary>
188 /// Adds a land object to the stored list and adds them to the landIDList to what they own 188 /// Adds a land object to the stored list and adds them to the landIDList to what they own
189 /// </summary> 189 /// </summary>
190 /// <param name="new_land">The land object being added</param> 190 /// <param name="new_land">The land object being added</param>
191 public ILandObject addLandObject(ILandObject new_land) 191 public ILandObject addLandObject(ILandObject new_land)
192 { 192 {
193 lastLandLocalID++; 193 lastLandLocalID++;
194 new_land.landData.localID = lastLandLocalID; 194 new_land.landData.localID = lastLandLocalID;
195 landList.Add(lastLandLocalID, (LandObject) new_land.Copy()); 195 landList.Add(lastLandLocalID, (LandObject) new_land.Copy());
196 196
197 197
198 bool[,] landBitmap = new_land.getLandBitmap(); 198 bool[,] landBitmap = new_land.getLandBitmap();
199 int x, y; 199 int x, y;
200 for (x = 0; x < 64; x++) 200 for (x = 0; x < 64; x++)
201 { 201 {
202 for (y = 0; y < 64; y++) 202 for (y = 0; y < 64; y++)
203 { 203 {
204 if (landBitmap[x, y]) 204 if (landBitmap[x, y])
205 { 205 {
206 landIDList[x, y] = lastLandLocalID; 206 landIDList[x, y] = lastLandLocalID;
207 } 207 }
208 } 208 }
209 } 209 }
210 landList[lastLandLocalID].forceUpdateLandInfo(); 210 landList[lastLandLocalID].forceUpdateLandInfo();
211 m_scene.EventManager.TriggerLandObjectAdded(new_land); 211 m_scene.EventManager.TriggerLandObjectAdded(new_land);
212 return new_land; 212 return new_land;
213 } 213 }
214 214
215 /// <summary> 215 /// <summary>
216 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList 216 /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList
217 /// </summary> 217 /// </summary>
218 /// <param name="local_id">Land.localID of the peice of land to remove.</param> 218 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
219 public void removeLandObject(int local_id) 219 public void removeLandObject(int local_id)
220 { 220 {
221 int x, y; 221 int x, y;
222 for (x = 0; x < 64; x++) 222 for (x = 0; x < 64; x++)
223 { 223 {
224 for (y = 0; y < 64; y++) 224 for (y = 0; y < 64; y++)
225 { 225 {
226 if (landIDList[x, y] == local_id) 226 if (landIDList[x, y] == local_id)
227 { 227 {
228 return; 228 return;
229 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); 229 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
230 } 230 }
231 } 231 }
232 } 232 }
233 233
234 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID); 234 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.globalID);
235 landList.Remove(local_id); 235 landList.Remove(local_id);
236 } 236 }
237 237
238 private void performFinalLandJoin(ILandObject master, ILandObject slave) 238 private void performFinalLandJoin(ILandObject master, ILandObject slave)
239 { 239 {
240 int x, y; 240 int x, y;
241 bool[,] landBitmapSlave = slave.getLandBitmap(); 241 bool[,] landBitmapSlave = slave.getLandBitmap();
242 for (x = 0; x < 64; x++) 242 for (x = 0; x < 64; x++)
243 { 243 {
244 for (y = 0; y < 64; y++) 244 for (y = 0; y < 64; y++)
245 { 245 {
246 if (landBitmapSlave[x, y]) 246 if (landBitmapSlave[x, y])
247 { 247 {
248 landIDList[x, y] = master.landData.localID; 248 landIDList[x, y] = master.landData.localID;
249 } 249 }
250 } 250 }
251 } 251 }
252 252
253 removeLandObject(slave.landData.localID); 253 removeLandObject(slave.landData.localID);
254 updateLandObject(master.landData.localID, master.landData); 254 updateLandObject(master.landData.localID, master.landData);
255 } 255 }
256 256
257 public ILandObject getLandObject(int parcelLocalID) 257 public ILandObject getLandObject(int parcelLocalID)
258 { 258 {
259 lock (landList) 259 lock (landList)
260 { 260 {
261 if (landList.ContainsKey(parcelLocalID)) 261 if (landList.ContainsKey(parcelLocalID))
262 { 262 {
263 return landList[parcelLocalID]; 263 return landList[parcelLocalID];
264 } 264 }
265 } 265 }
266 return null; 266 return null;
267 } 267 }
268 268
269 #endregion 269 #endregion
270 270
271 #region Parcel Modification 271 #region Parcel Modification
272 272
273 public void resetAllLandPrimCounts() 273 public void resetAllLandPrimCounts()
274 { 274 {
275 foreach (LandObject p in landList.Values) 275 foreach (LandObject p in landList.Values)
276 { 276 {
277 p.resetLandPrimCounts(); 277 p.resetLandPrimCounts();
278 } 278 }
279 } 279 }
280 280
281 public void setPrimsTainted() 281 public void setPrimsTainted()
282 { 282 {
283 landPrimCountTainted = true; 283 landPrimCountTainted = true;
284 } 284 }
285 285
286 public bool isLandPrimCountTainted() 286 public bool isLandPrimCountTainted()
287 { 287 {
288 return landPrimCountTainted; 288 return landPrimCountTainted;
289 } 289 }
290 290
291 public void addPrimToLandPrimCounts(SceneObjectGroup obj) 291 public void addPrimToLandPrimCounts(SceneObjectGroup obj)
292 { 292 {
293 LLVector3 position = obj.AbsolutePosition; 293 LLVector3 position = obj.AbsolutePosition;
294 ILandObject landUnderPrim = getLandObject(position.X, position.Y); 294 ILandObject landUnderPrim = getLandObject(position.X, position.Y);
295 if (landUnderPrim != null) 295 if (landUnderPrim != null)
296 { 296 {
297 landUnderPrim.addPrimToCount(obj); 297 landUnderPrim.addPrimToCount(obj);
298 } 298 }
299 } 299 }
300 300
301 public void removePrimFromLandPrimCounts(SceneObjectGroup obj) 301 public void removePrimFromLandPrimCounts(SceneObjectGroup obj)
302 { 302 {
303 foreach (LandObject p in landList.Values) 303 foreach (LandObject p in landList.Values)
304 { 304 {
305 p.removePrimFromCount(obj); 305 p.removePrimFromCount(obj);
306 } 306 }
307 } 307 }
308 308
309 public void finalizeLandPrimCountUpdate() 309 public void finalizeLandPrimCountUpdate()
310 { 310 {
311 //Get Simwide prim count for owner 311 //Get Simwide prim count for owner
312 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>(); 312 Dictionary<LLUUID, List<LandObject>> landOwnersAndParcels = new Dictionary<LLUUID, List<LandObject>>();
313 foreach (LandObject p in landList.Values) 313 foreach (LandObject p in landList.Values)
314 { 314 {
315 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) 315 if (!landOwnersAndParcels.ContainsKey(p.landData.ownerID))
316 { 316 {
317 List<LandObject> tempList = new List<LandObject>(); 317 List<LandObject> tempList = new List<LandObject>();
318 tempList.Add(p); 318 tempList.Add(p);
319 landOwnersAndParcels.Add(p.landData.ownerID, tempList); 319 landOwnersAndParcels.Add(p.landData.ownerID, tempList);
320 } 320 }
321 else 321 else
322 { 322 {
323 landOwnersAndParcels[p.landData.ownerID].Add(p); 323 landOwnersAndParcels[p.landData.ownerID].Add(p);
324 } 324 }
325 } 325 }
326 326
327 foreach (LLUUID owner in landOwnersAndParcels.Keys) 327 foreach (LLUUID owner in landOwnersAndParcels.Keys)
328 { 328 {
329 int simArea = 0; 329 int simArea = 0;
330 int simPrims = 0; 330 int simPrims = 0;
331 foreach (LandObject p in landOwnersAndParcels[owner]) 331 foreach (LandObject p in landOwnersAndParcels[owner])
332 { 332 {
333 simArea += p.landData.area; 333 simArea += p.landData.area;
334 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + 334 simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims +
335 p.landData.selectedPrims; 335 p.landData.selectedPrims;
336 } 336 }
337 337
338 foreach (LandObject p in landOwnersAndParcels[owner]) 338 foreach (LandObject p in landOwnersAndParcels[owner])
339 { 339 {
340 p.landData.simwideArea = simArea; 340 p.landData.simwideArea = simArea;
341 p.landData.simwidePrims = simPrims; 341 p.landData.simwidePrims = simPrims;
342 } 342 }
343 } 343 }
344 } 344 }
345 345
346 public void updateLandPrimCounts() 346 public void updateLandPrimCounts()
347 { 347 {
348 foreach (EntityBase obj in m_scene.Entities.Values) 348 foreach (EntityBase obj in m_scene.Entities.Values)
349 { 349 {
350 if (obj is SceneObjectGroup) 350 if (obj is SceneObjectGroup)
351 { 351 {
352 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj); 352 m_scene.EventManager.TriggerParcelPrimCountAdd((SceneObjectGroup) obj);
353 } 353 }
354 } 354 }
355 } 355 }
356 356
357 public void performParcelPrimCountUpdate() 357 public void performParcelPrimCountUpdate()
358 { 358 {
359 resetAllLandPrimCounts(); 359 resetAllLandPrimCounts();
360 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 360 m_scene.EventManager.TriggerParcelPrimCountUpdate();
361 finalizeLandPrimCountUpdate(); 361 finalizeLandPrimCountUpdate();
362 landPrimCountTainted = false; 362 landPrimCountTainted = false;
363 } 363 }
364 364
365 /// <summary> 365 /// <summary>
366 /// Subdivides a piece of land 366 /// Subdivides a piece of land
367 /// </summary> 367 /// </summary>
368 /// <param name="start_x">West Point</param> 368 /// <param name="start_x">West Point</param>
369 /// <param name="start_y">South Point</param> 369 /// <param name="start_y">South Point</param>
370 /// <param name="end_x">East Point</param> 370 /// <param name="end_x">East Point</param>
371 /// <param name="end_y">North Point</param> 371 /// <param name="end_y">North Point</param>
372 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> 372 /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param>
373 /// <returns>Returns true if successful</returns> 373 /// <returns>Returns true if successful</returns>
374 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 374 private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
375 { 375 {
376 //First, lets loop through the points and make sure they are all in the same peice of land 376 //First, lets loop through the points and make sure they are all in the same peice of land
377 //Get the land object at start 377 //Get the land object at start
378 ILandObject startLandObject = null; 378 ILandObject startLandObject = null;
379 try 379 try
380 { 380 {
381 startLandObject = getLandObject(start_x, start_y); 381 startLandObject = getLandObject(start_x, start_y);
382 } 382 }
383 catch (Exception) 383 catch (Exception)
384 { 384 {
385 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y); 385 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + start_x + " y:" + start_y);
386 } 386 }
387 if (startLandObject == null) return false; //No such land object at the beginning 387 if (startLandObject == null) return false; //No such land object at the beginning
388 388
389 //Loop through the points 389 //Loop through the points
390 try 390 try
391 { 391 {
392 int totalX = end_x - start_x; 392 int totalX = end_x - start_x;
393 int totalY = end_y - start_y; 393 int totalY = end_y - start_y;
394 int x, y; 394 int x, y;
395 for (y = 0; y < totalY; y++) 395 for (y = 0; y < totalY; y++)
396 { 396 {
397 for (x = 0; x < totalX; x++) 397 for (x = 0; x < totalX; x++)
398 { 398 {
399 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y); 399 ILandObject tempLandObject = getLandObject(start_x + x, start_y + y);
400 if (tempLandObject == null) return false; //No such land object at that point 400 if (tempLandObject == null) return false; //No such land object at that point
401 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no 401 if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no
402 } 402 }
403 } 403 }
404 } 404 }
405 catch (Exception) 405 catch (Exception)
406 { 406 {
407 return false; //Exception. For now, lets skip subdivision 407 return false; //Exception. For now, lets skip subdivision
408 } 408 }
409 409
410 //If we are still here, then they are subdividing within one piece of land 410 //If we are still here, then they are subdividing within one piece of land
411 //Check owner 411 //Check owner
412 if (startLandObject.landData.ownerID != attempting_user_id) 412 if (startLandObject.landData.ownerID != attempting_user_id)
413 { 413 {
414 return false; //They cant do this! 414 return false; //They cant do this!
415 } 415 }
416 416
417 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) 417 //Lets create a new land object with bitmap activated at that point (keeping the old land objects info)
418 ILandObject newLand = startLandObject.Copy(); 418 ILandObject newLand = startLandObject.Copy();
419 newLand.landData.landName = "Subdivision of " + newLand.landData.landName; 419 newLand.landData.landName = "Subdivision of " + newLand.landData.landName;
420 newLand.landData.globalID = LLUUID.Random(); 420 newLand.landData.globalID = LLUUID.Random();
421 421
422 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y)); 422 newLand.setLandBitmap(newLand.getSquareLandBitmap(start_x, start_y, end_x, end_y));
423 423
424 //Now, lets set the subdivision area of the original to false 424 //Now, lets set the subdivision area of the original to false
425 int startLandObjectIndex = startLandObject.landData.localID; 425 int startLandObjectIndex = startLandObject.landData.localID;
426 landList[startLandObjectIndex].setLandBitmap( 426 landList[startLandObjectIndex].setLandBitmap(
427 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); 427 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false));
428 landList[startLandObjectIndex].forceUpdateLandInfo(); 428 landList[startLandObjectIndex].forceUpdateLandInfo();
429 429
430 setPrimsTainted(); 430 setPrimsTainted();
431 431
432 //Now add the new land object 432 //Now add the new land object
433 ILandObject result = addLandObject(newLand); 433 ILandObject result = addLandObject(newLand);
434 updateLandObject(startLandObject.landData.localID, startLandObject.landData); 434 updateLandObject(startLandObject.landData.localID, startLandObject.landData);
435 result.sendLandUpdateToAvatarsOverMe(); 435 result.sendLandUpdateToAvatarsOverMe();
436 436
437 437
438 return true; 438 return true;
439 } 439 }
440 440
441 /// <summary> 441 /// <summary>
442 /// Join 2 land objects together 442 /// Join 2 land objects together
443 /// </summary> 443 /// </summary>
444 /// <param name="start_x">x value in first piece of land</param> 444 /// <param name="start_x">x value in first piece of land</param>
445 /// <param name="start_y">y value in first piece of land</param> 445 /// <param name="start_y">y value in first piece of land</param>
446 /// <param name="end_x">x value in second peice of land</param> 446 /// <param name="end_x">x value in second peice of land</param>
447 /// <param name="end_y">y value in second peice of land</param> 447 /// <param name="end_y">y value in second peice of land</param>
448 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> 448 /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param>
449 /// <returns>Returns true if successful</returns> 449 /// <returns>Returns true if successful</returns>
450 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) 450 private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id)
451 { 451 {
452 end_x -= 4; 452 end_x -= 4;
453 end_y -= 4; 453 end_y -= 4;
454 454
455 List<ILandObject> selectedLandObjects = new List<ILandObject>(); 455 List<ILandObject> selectedLandObjects = new List<ILandObject>();
456 int stepXSelected = 0; 456 int stepXSelected = 0;
457 int stepYSelected = 0; 457 int stepYSelected = 0;
458 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) 458 for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4)
459 { 459 {
460 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) 460 for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4)
461 { 461 {
462 ILandObject p = null; 462 ILandObject p = null;
463 try 463 try
464 { 464 {
465 p = getLandObject(stepXSelected, stepYSelected); 465 p = getLandObject(stepXSelected, stepYSelected);
466 } 466 }
467 catch (Exception) 467 catch (Exception)
468 { 468 {
469 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected); 469 //m_log.Error("[LAND]: " + "Unable to get land object for subdivision at x: " + stepXSelected + " y:" + stepYSelected);
470 } 470 }
471 if (p != null) 471 if (p != null)
472 { 472 {
473 if (!selectedLandObjects.Contains(p)) 473 if (!selectedLandObjects.Contains(p))
474 { 474 {
475 selectedLandObjects.Add(p); 475 selectedLandObjects.Add(p);
476 } 476 }
477 } 477 }
478 } 478 }
479 } 479 }
480 ILandObject masterLandObject = selectedLandObjects[0]; 480 ILandObject masterLandObject = selectedLandObjects[0];
481 selectedLandObjects.RemoveAt(0); 481 selectedLandObjects.RemoveAt(0);
482 482
483 483
484 if (selectedLandObjects.Count < 1) 484 if (selectedLandObjects.Count < 1)
485 { 485 {
486 return false; //Only one piece of land selected 486 return false; //Only one piece of land selected
487 } 487 }
488 if (masterLandObject.landData.ownerID != attempting_user_id) 488 if (masterLandObject.landData.ownerID != attempting_user_id)
489 { 489 {
490 return false; //Not the same owner 490 return false; //Not the same owner
491 } 491 }
492 foreach (ILandObject p in selectedLandObjects) 492 foreach (ILandObject p in selectedLandObjects)
493 { 493 {
494 if (p.landData.ownerID != masterLandObject.landData.ownerID) 494 if (p.landData.ownerID != masterLandObject.landData.ownerID)
495 { 495 {
496 return false; //Over multiple users. TODO: make this just ignore this piece of land? 496 return false; //Over multiple users. TODO: make this just ignore this piece of land?
497 } 497 }
498 } 498 }
499 foreach (ILandObject slaveLandObject in selectedLandObjects) 499 foreach (ILandObject slaveLandObject in selectedLandObjects)
500 { 500 {
501 landList[masterLandObject.landData.localID].setLandBitmap( 501 landList[masterLandObject.landData.localID].setLandBitmap(
502 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); 502 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap()));
503 performFinalLandJoin(masterLandObject, slaveLandObject); 503 performFinalLandJoin(masterLandObject, slaveLandObject);
504 } 504 }
505 505
506 506
507 setPrimsTainted(); 507 setPrimsTainted();
508 508
509 masterLandObject.sendLandUpdateToAvatarsOverMe(); 509 masterLandObject.sendLandUpdateToAvatarsOverMe();
510 510
511 return true; 511 return true;
512 } 512 }
513 513
514 #endregion 514 #endregion
515 515
516 #region Parcel Updating 516 #region Parcel Updating
517 517
518 /// <summary> 518 /// <summary>
519 /// Where we send the ParcelOverlay packet to the client 519 /// Where we send the ParcelOverlay packet to the client
520 /// </summary> 520 /// </summary>
521 /// <param name="remote_client">The object representing the client</param> 521 /// <param name="remote_client">The object representing the client</param>
522 public void sendParcelOverlay(IClientAPI remote_client) 522 public void sendParcelOverlay(IClientAPI remote_client)
523 { 523 {
524 const int LAND_BLOCKS_PER_PACKET = 1024; 524 const int LAND_BLOCKS_PER_PACKET = 1024;
525 int x, y = 0; 525 int x, y = 0;
526 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 526 byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET];
527 int byteArrayCount = 0; 527 int byteArrayCount = 0;
528 int sequenceID = 0; 528 int sequenceID = 0;
529 ParcelOverlayPacket packet; 529 ParcelOverlayPacket packet;
530 530
531 for (y = 0; y < 64; y++) 531 for (y = 0; y < 64; y++)
532 { 532 {
533 for (x = 0; x < 64; x++) 533 for (x = 0; x < 64; x++)
534 { 534 {
535 byte tempByte = (byte) 0; //This represents the byte for the current 4x4 535 byte tempByte = (byte) 0; //This represents the byte for the current 4x4
536 ILandObject currentParcelBlock = null; 536 ILandObject currentParcelBlock = null;
537 537
538 try 538 try
539 { 539 {
540 currentParcelBlock = getLandObject(x * 4, y * 4); 540 currentParcelBlock = getLandObject(x * 4, y * 4);
541 } 541 }
542 catch (Exception) 542 catch (Exception)
543 { 543 {
544 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4)); 544 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (x * 4) + " y: " + (y * 4));
545 } 545 }
546 546
547 547
548 if (currentParcelBlock != null) 548 if (currentParcelBlock != null)
549 { 549 {
550 if (currentParcelBlock.landData.ownerID == remote_client.AgentId) 550 if (currentParcelBlock.landData.ownerID == remote_client.AgentId)
551 { 551 {
552 //Owner Flag 552 //Owner Flag
553 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); 553 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER);
554 } 554 }
555 else if (currentParcelBlock.landData.salePrice > 0 && 555 else if (currentParcelBlock.landData.salePrice > 0 &&
556 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || 556 (currentParcelBlock.landData.authBuyerID == LLUUID.Zero ||
557 currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) 557 currentParcelBlock.landData.authBuyerID == remote_client.AgentId))
558 { 558 {
559 //Sale Flag 559 //Sale Flag
560 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); 560 tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE);
561 } 561 }
562 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) 562 else if (currentParcelBlock.landData.ownerID == LLUUID.Zero)
563 { 563 {
564 //Public Flag 564 //Public Flag
565 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); 565 tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC);
566 } 566 }
567 else 567 else
568 { 568 {
569 //Other Flag 569 //Other Flag
570 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); 570 tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER);
571 } 571 }
572 572
573 573
574 //Now for border control 574 //Now for border control
575 try 575 try
576 { 576 {
577 ILandObject westParcel = null; 577 ILandObject westParcel = null;
578 ILandObject southParcel = null; 578 ILandObject southParcel = null;
579 if (x > 0) 579 if (x > 0)
580 { 580 {
581 westParcel = getLandObject((x - 1) * 4, y * 4); 581 westParcel = getLandObject((x - 1) * 4, y * 4);
582 } 582 }
583 if (y > 0) 583 if (y > 0)
584 { 584 {
585 southParcel = getLandObject(x * 4, (y - 1) * 4); 585 southParcel = getLandObject(x * 4, (y - 1) * 4);
586 } 586 }
587 587
588 if (x == 0) 588 if (x == 0)
589 { 589 {
590 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); 590 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
591 } 591 }
592 else if (westParcel != null && westParcel != currentParcelBlock) 592 else if (westParcel != null && westParcel != currentParcelBlock)
593 { 593 {
594 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); 594 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST);
595 } 595 }
596 596
597 if (y == 0) 597 if (y == 0)
598 { 598 {
599 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); 599 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
600 } 600 }
601 else if (southParcel != null && southParcel != currentParcelBlock) 601 else if (southParcel != null && southParcel != currentParcelBlock)
602 { 602 {
603 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); 603 tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH);
604 } 604 }
605 605
606 byteArray[byteArrayCount] = tempByte; 606 byteArray[byteArrayCount] = tempByte;
607 byteArrayCount++; 607 byteArrayCount++;
608 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) 608 if (byteArrayCount >= LAND_BLOCKS_PER_PACKET)
609 { 609 {
610 byteArrayCount = 0; 610 byteArrayCount = 0;
611 packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay); 611 packet = (ParcelOverlayPacket) PacketPool.Instance.GetPacket(PacketType.ParcelOverlay);
612 packet.ParcelData.Data = byteArray; 612 packet.ParcelData.Data = byteArray;
613 packet.ParcelData.SequenceID = sequenceID; 613 packet.ParcelData.SequenceID = sequenceID;
614 remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task); 614 remote_client.OutPacket((Packet) packet, ThrottleOutPacketType.Task);
615 sequenceID++; 615 sequenceID++;
616 byteArray = new byte[LAND_BLOCKS_PER_PACKET]; 616 byteArray = new byte[LAND_BLOCKS_PER_PACKET];
617 } 617 }
618 } 618 }
619 catch (Exception) 619 catch (Exception)
620 { 620 {
621 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message); 621 //m_log.Debug("[LAND]: Skipped Land checks because avatar is out of bounds: " + e.Message);
622 } 622 }
623 } 623 }
624 } 624 }
625 } 625 }
626 } 626 }
627 627
628 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, 628 public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id,
629 bool snap_selection, IClientAPI remote_client) 629 bool snap_selection, IClientAPI remote_client)
630 { 630 {
631 //Get the land objects within the bounds 631 //Get the land objects within the bounds
632 List<ILandObject> temp = new List<ILandObject>(); 632 List<ILandObject> temp = new List<ILandObject>();
633 int x, y, i; 633 int x, y, i;
634 int inc_x = end_x - start_x; 634 int inc_x = end_x - start_x;
635 int inc_y = end_y - start_y; 635 int inc_y = end_y - start_y;
636 for (x = 0; x < inc_x; x++) 636 for (x = 0; x < inc_x; x++)
637 { 637 {
638 for (y = 0; y < inc_y; y++) 638 for (y = 0; y < inc_y; y++)
639 { 639 {
640 ILandObject currentParcel = null; 640 ILandObject currentParcel = null;
641 try 641 try
642 { 642 {
643 currentParcel = getLandObject(start_x + x, start_y + y); 643 currentParcel = getLandObject(start_x + x, start_y + y);
644 } 644 }
645 catch (Exception) 645 catch (Exception)
646 { 646 {
647 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y)); 647 //m_log.Warn("[LAND]: " + "unable to get land at x: " + (start_x + x) + " y: " + (start_y + y));
648 } 648 }
649 if (currentParcel != null) 649 if (currentParcel != null)
650 { 650 {
651 if (!temp.Contains(currentParcel)) 651 if (!temp.Contains(currentParcel))
652 { 652 {
653 currentParcel.forceUpdateLandInfo(); 653 currentParcel.forceUpdateLandInfo();
654 temp.Add(currentParcel); 654 temp.Add(currentParcel);
655 } 655 }
656 } 656 }
657 } 657 }
658 } 658 }
659 659
660 int requestResult = LAND_RESULT_SINGLE; 660 int requestResult = LAND_RESULT_SINGLE;
661 if (temp.Count > 1) 661 if (temp.Count > 1)
662 { 662 {
663 requestResult = LAND_RESULT_MULTIPLE; 663 requestResult = LAND_RESULT_MULTIPLE;
664 } 664 }
665 665
666 for (i = 0; i < temp.Count; i++) 666 for (i = 0; i < temp.Count; i++)
667 { 667 {
668 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); 668 temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client);
669 } 669 }
670 670
671 671
672 sendParcelOverlay(remote_client); 672 sendParcelOverlay(remote_client);
673 } 673 }
674 674
675 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) 675 public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
676 { 676 {
677 if (landList.ContainsKey(packet.ParcelData.LocalID)) 677 if (landList.ContainsKey(packet.ParcelData.LocalID))
678 { 678 {
679 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); 679 landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client);
680 } 680 }
681 } 681 }
682 682
683 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) 683 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
684 { 684 {
685 subdivide(west, south, east, north, remote_client.AgentId); 685 subdivide(west, south, east, north, remote_client.AgentId);
686 } 686 }
687 687
688 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) 688 public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client)
689 { 689 {
690 join(west, south, east, north, remote_client.AgentId); 690 join(west, south, east, north, remote_client.AgentId);
691 } 691 }
692 692
693 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) 693 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
694 { 694 {
695 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); 695 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
696 } 696 }
697 697
698 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) 698 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
699 { 699 {
700 landList[local_id].sendLandObjectOwners(remote_client); 700 landList[local_id].sendLandObjectOwners(remote_client);
701 } 701 }
702 702
703 #endregion 703 #endregion
704 704
705 #region ILandChannel Members 705 #region ILandChannel Members
706 706
707 public bool allowedForcefulBans 707 public bool allowedForcefulBans
708 { 708 {
709 get { return m_allowedForcefulBans; } 709 get { return m_allowedForcefulBans; }
710 set { m_allowedForcefulBans = value; } 710 set { m_allowedForcefulBans = value; }
711 } 711 }
712 712
713 /// <summary> 713 /// <summary>
714 /// Resets the sim to the default land object (full sim piece of land owned by the default user) 714 /// Resets the sim to the default land object (full sim piece of land owned by the default user)
715 /// </summary> 715 /// </summary>
716 public void resetSimLandObjects() 716 public void resetSimLandObjects()
717 { 717 {
718 //Remove all the land objects in the sim and add a blank, full sim land object set to public 718 //Remove all the land objects in the sim and add a blank, full sim land object set to public
719 landList.Clear(); 719 landList.Clear();
720 lastLandLocalID = START_LAND_LOCAL_ID - 1; 720 lastLandLocalID = START_LAND_LOCAL_ID - 1;
721 landIDList.Initialize(); 721 landIDList.Initialize();
722 722
723 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene); 723 ILandObject fullSimParcel = new LandObject(LLUUID.Zero, false, m_scene);
724 724
725 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize)); 725 fullSimParcel.setLandBitmap(fullSimParcel.getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize));
726 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 726 fullSimParcel.landData.ownerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
727 727
728 addLandObject(fullSimParcel); 728 addLandObject(fullSimParcel);
729 } 729 }
730 730
731 public List<ILandObject> parcelsNearPoint(LLVector3 position) 731 public List<ILandObject> parcelsNearPoint(LLVector3 position)
732 { 732 {
733 List<ILandObject> parcelsNear = new List<ILandObject>(); 733 List<ILandObject> parcelsNear = new List<ILandObject>();
734 int x, y; 734 int x, y;
735 for (x = -4; x <= 4; x += 4) 735 for (x = -4; x <= 4; x += 4)
736 { 736 {
737 for (y = -4; y <= 4; y += 4) 737 for (y = -4; y <= 4; y += 4)
738 { 738 {
739 ILandObject check = getLandObject(position.X + x, position.Y + y); 739 ILandObject check = getLandObject(position.X + x, position.Y + y);
740 if (check != null) 740 if (check != null)
741 { 741 {
742 if (!parcelsNear.Contains(check)) 742 if (!parcelsNear.Contains(check))
743 { 743 {
744 parcelsNear.Add(check); 744 parcelsNear.Add(check);
745 } 745 }
746 } 746 }
747 } 747 }
748 } 748 }
749 749
750 return parcelsNear; 750 return parcelsNear;
751 } 751 }
752 752
753 public void sendYouAreBannedNotice(ScenePresence avatar) 753 public void sendYouAreBannedNotice(ScenePresence avatar)
754 { 754 {
755 if (allowedForcefulBans) 755 if (allowedForcefulBans)
756 { 756 {
757 avatar.ControllingClient.SendAlertMessage( 757 avatar.ControllingClient.SendAlertMessage(
758 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers"); 758 "You are not allowed on this parcel because you are banned. Please go away. <3 OpenSim Developers");
759 759
760 avatar.PhysicsActor.Position = 760 avatar.PhysicsActor.Position =
761 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y, 761 new PhysicsVector(avatar.lastKnownAllowedPosition.x, avatar.lastKnownAllowedPosition.y,
762 avatar.lastKnownAllowedPosition.z); 762 avatar.lastKnownAllowedPosition.z);
763 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0); 763 avatar.PhysicsActor.Velocity = new PhysicsVector(0, 0, 0);
764 } 764 }
765 else 765 else
766 { 766 {
767 avatar.ControllingClient.SendAlertMessage( 767 avatar.ControllingClient.SendAlertMessage(
768 "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim! <3 OpenSim Developers"); 768 "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim! <3 OpenSim Developers");
769 } 769 }
770 } 770 }
771 771
772 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 772 public void handleAvatarChangingParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
773 { 773 {
774 if (m_scene.RegionInfo.RegionID == regionID) 774 if (m_scene.RegionInfo.RegionID == regionID)
775 { 775 {
776 if (landList[localLandID] != null) 776 if (landList[localLandID] != null)
777 { 777 {
778 ILandObject parcelAvatarIsEntering = landList[localLandID]; 778 ILandObject parcelAvatarIsEntering = landList[localLandID];
779 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT) 779 if (avatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT)
780 { 780 {
781 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) 781 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID))
782 { 782 {
783 sendYouAreBannedNotice(avatar); 783 sendYouAreBannedNotice(avatar);
784 } 784 }
785 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID)) 785 else if (parcelAvatarIsEntering.isRestrictedFromLand(avatar.UUID))
786 { 786 {
787 avatar.ControllingClient.SendAlertMessage( 787 avatar.ControllingClient.SendAlertMessage(
788 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers"); 788 "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!). <3 OpenSim Developers");
789 } 789 }
790 else 790 else
791 { 791 {
792 avatar.sentMessageAboutRestrictedParcelFlyingDown = true; 792 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
793 } 793 }
794 } 794 }
795 else 795 else
796 { 796 {
797 avatar.sentMessageAboutRestrictedParcelFlyingDown = true; 797 avatar.sentMessageAboutRestrictedParcelFlyingDown = true;
798 } 798 }
799 } 799 }
800 } 800 }
801 } 801 }
802 802
803 public void sendOutNearestBanLine(IClientAPI avatar) 803 public void sendOutNearestBanLine(IClientAPI avatar)
804 { 804 {
805 List<ScenePresence> avatars = m_scene.GetAvatars(); 805 List<ScenePresence> avatars = m_scene.GetAvatars();
806 foreach (ScenePresence presence in avatars) 806 foreach (ScenePresence presence in avatars)
807 { 807 {
808 if (presence.UUID == avatar.AgentId) 808 if (presence.UUID == avatar.AgentId)
809 { 809 {
810 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition); 810 List<ILandObject> checkLandParcels = parcelsNearPoint(presence.AbsolutePosition);
811 foreach (ILandObject checkBan in checkLandParcels) 811 foreach (ILandObject checkBan in checkLandParcels)
812 { 812 {
813 if (checkBan.isBannedFromLand(avatar.AgentId)) 813 if (checkBan.isBannedFromLand(avatar.AgentId))
814 { 814 {
815 checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar); 815 checkBan.sendLandProperties(-30000, false, (int) ParcelManager.ParcelResult.Single, avatar);
816 return; //Only send one 816 return; //Only send one
817 } 817 }
818 else if (checkBan.isRestrictedFromLand(avatar.AgentId)) 818 else if (checkBan.isRestrictedFromLand(avatar.AgentId))
819 { 819 {
820 checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar); 820 checkBan.sendLandProperties(-40000, false, (int) ParcelManager.ParcelResult.Single, avatar);
821 return; //Only send one 821 return; //Only send one
822 } 822 }
823 } 823 }
824 return; 824 return;
825 } 825 }
826 } 826 }
827 } 827 }
828 828
829 public void sendLandUpdate(ScenePresence avatar, bool force) 829 public void sendLandUpdate(ScenePresence avatar, bool force)
830 { 830 {
831 ILandObject over = null; 831 ILandObject over = null;
832 try 832 try
833 { 833 {
834 over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), 834 over = getLandObject((int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.X))),
835 (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); 835 (int) Math.Min(255, Math.Max(0, Math.Round(avatar.AbsolutePosition.Y))));
836 } 836 }
837 catch (Exception) 837 catch (Exception)
838 { 838 {
839 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y)); 839 //m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + Math.Round(avatar.AbsolutePosition.Y));
840 } 840 }
841 841
842 if (over != null) 842 if (over != null)
843 { 843 {
844 if (force) 844 if (force)
845 { 845 {
846 if (!avatar.IsChildAgent) 846 if (!avatar.IsChildAgent)
847 { 847 {
848 over.sendLandUpdateToClient(avatar.ControllingClient); 848 over.sendLandUpdateToClient(avatar.ControllingClient);
849 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, 849 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
850 m_scene.RegionInfo.RegionID); 850 m_scene.RegionInfo.RegionID);
851 } 851 }
852 } 852 }
853 853
854 if (avatar.currentParcelUUID != over.landData.globalID) 854 if (avatar.currentParcelUUID != over.landData.globalID)
855 { 855 {
856 if (!avatar.IsChildAgent) 856 if (!avatar.IsChildAgent)
857 { 857 {
858 over.sendLandUpdateToClient(avatar.ControllingClient); 858 over.sendLandUpdateToClient(avatar.ControllingClient);
859 avatar.currentParcelUUID = over.landData.globalID; 859 avatar.currentParcelUUID = over.landData.globalID;
860 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID, 860 m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.landData.localID,
861 m_scene.RegionInfo.RegionID); 861 m_scene.RegionInfo.RegionID);
862 } 862 }
863 } 863 }
864 } 864 }
865 } 865 }
866 866
867 public void sendLandUpdate(ScenePresence avatar) 867 public void sendLandUpdate(ScenePresence avatar)
868 { 868 {
869 sendLandUpdate(avatar, false); 869 sendLandUpdate(avatar, false);
870 } 870 }
871 871
872 public void handleSignificantClientMovement(IClientAPI remote_client) 872 public void handleSignificantClientMovement(IClientAPI remote_client)
873 { 873 {
874 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId); 874 ScenePresence clientAvatar = m_scene.GetScenePresence(remote_client.AgentId);
875 875
876 if (clientAvatar != null) 876 if (clientAvatar != null)
877 { 877 {
878 sendLandUpdate(clientAvatar); 878 sendLandUpdate(clientAvatar);
879 sendOutNearestBanLine(remote_client); 879 sendOutNearestBanLine(remote_client);
880 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); 880 ILandObject parcel = getLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y);
881 if (parcel != null) 881 if (parcel != null)
882 { 882 {
883 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && 883 if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
884 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) 884 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown)
885 { 885 {
886 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID); 886 handleAvatarChangingParcel(clientAvatar, parcel.landData.localID, m_scene.RegionInfo.RegionID);
887 //They are going below the safety line! 887 //They are going below the safety line!
888 if (!parcel.isBannedFromLand(clientAvatar.UUID)) 888 if (!parcel.isBannedFromLand(clientAvatar.UUID))
889 { 889 {
890 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; 890 clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false;
891 } 891 }
892 } 892 }
893 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT && 893 else if (clientAvatar.AbsolutePosition.Z < BAN_LINE_SAFETY_HIEGHT &&
894 parcel.isBannedFromLand(clientAvatar.UUID)) 894 parcel.isBannedFromLand(clientAvatar.UUID))
895 { 895 {
896 sendYouAreBannedNotice(clientAvatar); 896 sendYouAreBannedNotice(clientAvatar);
897 } 897 }
898 } 898 }
899 } 899 }
900 } 900 }
901 901
902 public void handleAnyClientMovement(ScenePresence avatar) 902 public void handleAnyClientMovement(ScenePresence avatar)
903 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance. 903 //Like handleSignificantClientMovement, but called with an AgentUpdate regardless of distance.
904 { 904 {
905 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 905 ILandObject over = getLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
906 if (over != null) 906 if (over != null)
907 { 907 {
908 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT) 908 if (!over.isBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= BAN_LINE_SAFETY_HIEGHT)
909 { 909 {
910 avatar.lastKnownAllowedPosition = 910 avatar.lastKnownAllowedPosition =
911 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); 911 new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
912 } 912 }
913 } 913 }
914 } 914 }
915 915
916 916
917 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, 917 public void handleParcelAccessRequest(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
918 int landLocalID, IClientAPI remote_client) 918 int landLocalID, IClientAPI remote_client)
919 { 919 {
920 if (landList.ContainsKey(landLocalID)) 920 if (landList.ContainsKey(landLocalID))
921 { 921 {
922 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); 922 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client);
923 } 923 }
924 } 924 }
925 925
926 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID, 926 public void handleParcelAccessUpdateRequest(LLUUID agentID, LLUUID sessionID, uint flags, int landLocalID,
927 List<ParcelManager.ParcelAccessEntry> entries, 927 List<ParcelManager.ParcelAccessEntry> entries,
928 IClientAPI remote_client) 928 IClientAPI remote_client)
929 { 929 {
930 if (landList.ContainsKey(landLocalID)) 930 if (landList.ContainsKey(landLocalID))
931 { 931 {
932 if (agentID == landList[landLocalID].landData.ownerID) 932 if (agentID == landList[landLocalID].landData.ownerID)
933 { 933 {
934 landList[landLocalID].updateAccessList(flags, entries, remote_client); 934 landList[landLocalID].updateAccessList(flags, entries, remote_client);
935 } 935 }
936 } 936 }
937 else 937 else
938 { 938 {
939 Console.WriteLine("INVALID LOCAL LAND ID"); 939 Console.WriteLine("INVALID LOCAL LAND ID");
940 } 940 }
941 } 941 }
942 942
943 #endregion 943 #endregion
944 944
945 // If the economy has been validated by the economy module, 945 // If the economy has been validated by the economy module,
946 // and land has been validated as well, this method transfers 946 // and land has been validated as well, this method transfers
947 // the land ownership 947 // the land ownership
948 948
949 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e) 949 public void handleLandBuyRequest(Object o, EventManager.LandBuyArgs e)
950 { 950 {
951 if (e.economyValidated && e.landValidated) 951 if (e.economyValidated && e.landValidated)
952 { 952 {
953 lock (landList) 953 lock (landList)
954 { 954 {
955 if (landList.ContainsKey(e.parcelLocalID)) 955 if (landList.ContainsKey(e.parcelLocalID))
956 { 956 {
957 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea); 957 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint) e.transactionID, e.parcelPrice, e.parcelArea);
958 return; 958 return;
959 } 959 }
960 } 960 }
961 } 961 }
962 } 962 }
963 963
964 // After receiving a land buy packet, first the data needs to 964 // After receiving a land buy packet, first the data needs to
965 // be validated. This method validates the right to buy the 965 // be validated. This method validates the right to buy the
966 // parcel 966 // parcel
967 967
968 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e) 968 public void handleLandValidationRequest(Object o, EventManager.LandBuyArgs e)
969 { 969 {
970 if (e.landValidated == false) 970 if (e.landValidated == false)
971 { 971 {
972 ILandObject lob = null; 972 ILandObject lob = null;
973 lock (landList) 973 lock (landList)
974 { 974 {
975 if (landList.ContainsKey(e.parcelLocalID)) 975 if (landList.ContainsKey(e.parcelLocalID))
976 { 976 {
977 lob = landList[e.parcelLocalID]; 977 lob = landList[e.parcelLocalID];
978 } 978 }
979 } 979 }
980 if (lob != null) 980 if (lob != null)
981 { 981 {
982 LLUUID AuthorizedID = lob.landData.authBuyerID; 982 LLUUID AuthorizedID = lob.landData.authBuyerID;
983 int saleprice = lob.landData.salePrice; 983 int saleprice = lob.landData.salePrice;
984 LLUUID pOwnerID = lob.landData.ownerID; 984 LLUUID pOwnerID = lob.landData.ownerID;
985 985
986 bool landforsale = ((lob.landData.landFlags & 986 bool landforsale = ((lob.landData.landFlags &
987 (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); 987 (uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0);
988 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) 988 if ((AuthorizedID == LLUUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale)
989 { 989 {
990 lock (e) 990 lock (e)
991 { 991 {
992 e.parcelOwnerID = pOwnerID; 992 e.parcelOwnerID = pOwnerID;
993 e.landValidated = true; 993 e.landValidated = true;
994 } 994 }
995 } 995 }
996 } 996 }
997 } 997 }
998 } 998 }
999 } 999 }
1000} \ No newline at end of file 1000} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
index 3f09bd5..877bed5 100644
--- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
@@ -1,79 +1,79 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using Nini.Config; 28using Nini.Config;
29using OpenSim.Region.Environment.Interfaces; 29using OpenSim.Region.Environment.Interfaces;
30using OpenSim.Region.Environment.Scenes; 30using OpenSim.Region.Environment.Scenes;
31 31
32namespace OpenSim.Region.Environment.Modules.World.Land 32namespace OpenSim.Region.Environment.Modules.World.Land
33{ 33{
34 public class LandManagementModule : IRegionModule 34 public class LandManagementModule : IRegionModule
35 { 35 {
36 private LandChannel landChannel; 36 private LandChannel landChannel;
37 private Scene m_scene; 37 private Scene m_scene;
38 38
39 #region IRegionModule Members 39 #region IRegionModule Members
40 40
41 public void Initialise(Scene scene, IConfigSource source) 41 public void Initialise(Scene scene, IConfigSource source)
42 { 42 {
43 m_scene = scene; 43 m_scene = scene;
44 landChannel = new LandChannel(scene); 44 landChannel = new LandChannel(scene);
45 45
46 m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts; 46 m_scene.EventManager.OnParcelPrimCountAdd += landChannel.addPrimToLandPrimCounts;
47 m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts; 47 m_scene.EventManager.OnParcelPrimCountUpdate += landChannel.updateLandPrimCounts;
48 m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel); 48 m_scene.EventManager.OnAvatarEnteringNewParcel += new EventManager.AvatarEnteringNewParcel(landChannel.handleAvatarChangingParcel);
49 m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement); 49 m_scene.EventManager.OnClientMovement += new EventManager.ClientMovement(landChannel.handleAnyClientMovement);
50 m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest; 50 m_scene.EventManager.OnValidateLandBuy += landChannel.handleLandValidationRequest;
51 m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest; 51 m_scene.EventManager.OnLandBuy += landChannel.handleLandBuyRequest;
52 52
53 lock (m_scene) 53 lock (m_scene)
54 { 54 {
55 m_scene.LandChannel = (ILandChannel) landChannel; 55 m_scene.LandChannel = (ILandChannel) landChannel;
56 } 56 }
57 } 57 }
58 58
59 public void PostInitialise() 59 public void PostInitialise()
60 { 60 {
61 } 61 }
62 62
63 public void Close() 63 public void Close()
64 { 64 {
65 } 65 }
66 66
67 public string Name 67 public string Name
68 { 68 {
69 get { return "LandManagementModule"; } 69 get { return "LandManagementModule"; }
70 } 70 }
71 71
72 public bool IsSharedModule 72 public bool IsSharedModule
73 { 73 {
74 get { return false; } 74 get { return false; }
75 } 75 }
76 76
77 #endregion 77 #endregion
78 } 78 }
79} \ No newline at end of file 79} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
index 368e113..e297b10 100644
--- a/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandObject.cs
@@ -1,928 +1,928 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33using log4net; 33using log4net;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes; 36using OpenSim.Region.Environment.Scenes;
37 37
38namespace OpenSim.Region.Environment.Modules.World.Land 38namespace OpenSim.Region.Environment.Modules.World.Land
39{ 39{
40 /// <summary> 40 /// <summary>
41 /// Keeps track of a specific piece of land's information 41 /// Keeps track of a specific piece of land's information
42 /// </summary> 42 /// </summary>
43 public class LandObject : ILandObject 43 public class LandObject : ILandObject
44 { 44 {
45 #region Member Variables 45 #region Member Variables
46 46
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 private bool[,] m_landBitmap = new bool[64,64]; 48 private bool[,] m_landBitmap = new bool[64,64];
49 49
50 protected LandData m_landData = new LandData(); 50 protected LandData m_landData = new LandData();
51 protected Scene m_scene; 51 protected Scene m_scene;
52 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 52 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
53 53
54 public bool[,] landBitmap 54 public bool[,] landBitmap
55 { 55 {
56 get { return m_landBitmap; } 56 get { return m_landBitmap; }
57 set { m_landBitmap = value; } 57 set { m_landBitmap = value; }
58 } 58 }
59 59
60 #endregion 60 #endregion
61 61
62 #region ILandObject Members 62 #region ILandObject Members
63 63
64 public LandData landData 64 public LandData landData
65 { 65 {
66 get { return m_landData; } 66 get { return m_landData; }
67 67
68 set { m_landData = value; } 68 set { m_landData = value; }
69 } 69 }
70 70
71 public LLUUID regionUUID 71 public LLUUID regionUUID
72 { 72 {
73 get { return m_scene.RegionInfo.RegionID; } 73 get { return m_scene.RegionInfo.RegionID; }
74 } 74 }
75 75
76 #region Constructors 76 #region Constructors
77 77
78 public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene) 78 public LandObject(LLUUID owner_id, bool is_group_owned, Scene scene)
79 { 79 {
80 m_scene = scene; 80 m_scene = scene;
81 landData.ownerID = owner_id; 81 landData.ownerID = owner_id;
82 landData.isGroupOwned = is_group_owned; 82 landData.isGroupOwned = is_group_owned;
83 } 83 }
84 84
85 #endregion 85 #endregion
86 86
87 #region Member Functions 87 #region Member Functions
88 88
89 #region General Functions 89 #region General Functions
90 90
91 /// <summary> 91 /// <summary>
92 /// Checks to see if this land object contains a point 92 /// Checks to see if this land object contains a point
93 /// </summary> 93 /// </summary>
94 /// <param name="x"></param> 94 /// <param name="x"></param>
95 /// <param name="y"></param> 95 /// <param name="y"></param>
96 /// <returns>Returns true if the piece of land contains the specified point</returns> 96 /// <returns>Returns true if the piece of land contains the specified point</returns>
97 public bool containsPoint(int x, int y) 97 public bool containsPoint(int x, int y)
98 { 98 {
99 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) 99 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize)
100 { 100 {
101 return (landBitmap[x / 4, y / 4] == true); 101 return (landBitmap[x / 4, y / 4] == true);
102 } 102 }
103 else 103 else
104 { 104 {
105 return false; 105 return false;
106 } 106 }
107 } 107 }
108 108
109 public ILandObject Copy() 109 public ILandObject Copy()
110 { 110 {
111 ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene); 111 ILandObject newLand = new LandObject(landData.ownerID, landData.isGroupOwned, m_scene);
112 112
113 //Place all new variables here! 113 //Place all new variables here!
114 newLand.landBitmap = (bool[,]) (landBitmap.Clone()); 114 newLand.landBitmap = (bool[,]) (landBitmap.Clone());
115 newLand.landData = landData.Copy(); 115 newLand.landData = landData.Copy();
116 116
117 return newLand; 117 return newLand;
118 } 118 }
119 119
120 #endregion 120 #endregion
121 121
122 #region Packet Request Handling 122 #region Packet Request Handling
123 123
124 /// <summary> 124 /// <summary>
125 /// Sends land properties as requested 125 /// Sends land properties as requested
126 /// </summary> 126 /// </summary>
127 /// <param name="sequence_id">ID sent by client for them to keep track of</param> 127 /// <param name="sequence_id">ID sent by client for them to keep track of</param>
128 /// <param name="snap_selection">Bool sent by client for them to use</param> 128 /// <param name="snap_selection">Bool sent by client for them to use</param>
129 /// <param name="remote_client">Object representing the client</param> 129 /// <param name="remote_client">Object representing the client</param>
130 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, 130 public void sendLandProperties(int sequence_id, bool snap_selection, int request_result,
131 IClientAPI remote_client) 131 IClientAPI remote_client)
132 { 132 {
133 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties); 133 ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties);
134 // TODO: don't create new blocks if recycling an old packet 134 // TODO: don't create new blocks if recycling an old packet
135 135
136 updatePacket.ParcelData.AABBMax = landData.AABBMax; 136 updatePacket.ParcelData.AABBMax = landData.AABBMax;
137 updatePacket.ParcelData.AABBMin = landData.AABBMin; 137 updatePacket.ParcelData.AABBMin = landData.AABBMin;
138 updatePacket.ParcelData.Area = landData.area; 138 updatePacket.ParcelData.Area = landData.area;
139 updatePacket.ParcelData.AuctionID = landData.auctionID; 139 updatePacket.ParcelData.AuctionID = landData.auctionID;
140 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented 140 updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented
141 141
142 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; 142 updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray;
143 143
144 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); 144 updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc);
145 updatePacket.ParcelData.Category = (byte) landData.category; 145 updatePacket.ParcelData.Category = (byte) landData.category;
146 updatePacket.ParcelData.ClaimDate = landData.claimDate; 146 updatePacket.ParcelData.ClaimDate = landData.claimDate;
147 updatePacket.ParcelData.ClaimPrice = landData.claimPrice; 147 updatePacket.ParcelData.ClaimPrice = landData.claimPrice;
148 updatePacket.ParcelData.GroupID = landData.groupID; 148 updatePacket.ParcelData.GroupID = landData.groupID;
149 updatePacket.ParcelData.GroupPrims = landData.groupPrims; 149 updatePacket.ParcelData.GroupPrims = landData.groupPrims;
150 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; 150 updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned;
151 updatePacket.ParcelData.LandingType = (byte) landData.landingType; 151 updatePacket.ParcelData.LandingType = (byte) landData.landingType;
152 updatePacket.ParcelData.LocalID = landData.localID; 152 updatePacket.ParcelData.LocalID = landData.localID;
153 if (landData.area > 0) 153 if (landData.area > 0)
154 { 154 {
155 updatePacket.ParcelData.MaxPrims = 155 updatePacket.ParcelData.MaxPrims =
156 Convert.ToInt32( 156 Convert.ToInt32(
157 Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * 157 Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
158 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); 158 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
159 } 159 }
160 else 160 else
161 { 161 {
162 updatePacket.ParcelData.MaxPrims = 0; 162 updatePacket.ParcelData.MaxPrims = 0;
163 } 163 }
164 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; 164 updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale;
165 updatePacket.ParcelData.MediaID = landData.mediaID; 165 updatePacket.ParcelData.MediaID = landData.mediaID;
166 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); 166 updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL);
167 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); 167 updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL);
168 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); 168 updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName);
169 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented 169 updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented
170 updatePacket.ParcelData.OtherCount = 0; //unemplemented 170 updatePacket.ParcelData.OtherCount = 0; //unemplemented
171 updatePacket.ParcelData.OtherPrims = landData.otherPrims; 171 updatePacket.ParcelData.OtherPrims = landData.otherPrims;
172 updatePacket.ParcelData.OwnerID = landData.ownerID; 172 updatePacket.ParcelData.OwnerID = landData.ownerID;
173 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; 173 updatePacket.ParcelData.OwnerPrims = landData.ownerPrims;
174 updatePacket.ParcelData.ParcelFlags = landData.landFlags; 174 updatePacket.ParcelData.ParcelFlags = landData.landFlags;
175 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor; 175 updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor;
176 updatePacket.ParcelData.PassHours = landData.passHours; 176 updatePacket.ParcelData.PassHours = landData.passHours;
177 updatePacket.ParcelData.PassPrice = landData.passPrice; 177 updatePacket.ParcelData.PassPrice = landData.passPrice;
178 updatePacket.ParcelData.PublicCount = 0; //unemplemented 178 updatePacket.ParcelData.PublicCount = 0; //unemplemented
179 179
180 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags; 180 uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags;
181 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) > 181 updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) >
182 0); 182 0);
183 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) > 183 updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) >
184 0); 184 0);
185 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) > 185 updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) >
186 0); 186 0);
187 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) > 187 updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) >
188 0); 188 0);
189 189
190 updatePacket.ParcelData.RentPrice = 0; 190 updatePacket.ParcelData.RentPrice = 0;
191 updatePacket.ParcelData.RequestResult = request_result; 191 updatePacket.ParcelData.RequestResult = request_result;
192 updatePacket.ParcelData.SalePrice = landData.salePrice; 192 updatePacket.ParcelData.SalePrice = landData.salePrice;
193 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; 193 updatePacket.ParcelData.SelectedPrims = landData.selectedPrims;
194 updatePacket.ParcelData.SelfCount = 0; //unemplemented 194 updatePacket.ParcelData.SelfCount = 0; //unemplemented
195 updatePacket.ParcelData.SequenceID = sequence_id; 195 updatePacket.ParcelData.SequenceID = sequence_id;
196 if (landData.simwideArea > 0) 196 if (landData.simwideArea > 0)
197 { 197 {
198 updatePacket.ParcelData.SimWideMaxPrims = 198 updatePacket.ParcelData.SimWideMaxPrims =
199 Convert.ToInt32( 199 Convert.ToInt32(
200 Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * 200 Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * m_scene.objectCapacity *
201 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); 201 Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor)));
202 } 202 }
203 else 203 else
204 { 204 {
205 updatePacket.ParcelData.SimWideMaxPrims = 0; 205 updatePacket.ParcelData.SimWideMaxPrims = 0;
206 } 206 }
207 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; 207 updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims;
208 updatePacket.ParcelData.SnapSelection = snap_selection; 208 updatePacket.ParcelData.SnapSelection = snap_selection;
209 updatePacket.ParcelData.SnapshotID = landData.snapshotID; 209 updatePacket.ParcelData.SnapshotID = landData.snapshotID;
210 updatePacket.ParcelData.Status = (byte) landData.landStatus; 210 updatePacket.ParcelData.Status = (byte) landData.landStatus;
211 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + 211 updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims +
212 landData.selectedPrims; 212 landData.selectedPrims;
213 updatePacket.ParcelData.UserLocation = landData.userLocation; 213 updatePacket.ParcelData.UserLocation = landData.userLocation;
214 updatePacket.ParcelData.UserLookAt = landData.userLookAt; 214 updatePacket.ParcelData.UserLookAt = landData.userLookAt;
215 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task); 215 remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task);
216 } 216 }
217 217
218 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) 218 public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client)
219 { 219 {
220 if (remote_client.AgentId == landData.ownerID) 220 if (remote_client.AgentId == landData.ownerID)
221 { 221 {
222 //Needs later group support 222 //Needs later group support
223 LandData newData = landData.Copy(); 223 LandData newData = landData.Copy();
224 newData.authBuyerID = packet.ParcelData.AuthBuyerID; 224 newData.authBuyerID = packet.ParcelData.AuthBuyerID;
225 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category; 225 newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category;
226 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); 226 newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc);
227 newData.groupID = packet.ParcelData.GroupID; 227 newData.groupID = packet.ParcelData.GroupID;
228 newData.landingType = packet.ParcelData.LandingType; 228 newData.landingType = packet.ParcelData.LandingType;
229 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale; 229 newData.mediaAutoScale = packet.ParcelData.MediaAutoScale;
230 newData.mediaID = packet.ParcelData.MediaID; 230 newData.mediaID = packet.ParcelData.MediaID;
231 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); 231 newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL);
232 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); 232 newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL);
233 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); 233 newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name);
234 newData.landFlags = packet.ParcelData.ParcelFlags; 234 newData.landFlags = packet.ParcelData.ParcelFlags;
235 newData.passHours = packet.ParcelData.PassHours; 235 newData.passHours = packet.ParcelData.PassHours;
236 newData.passPrice = packet.ParcelData.PassPrice; 236 newData.passPrice = packet.ParcelData.PassPrice;
237 newData.salePrice = packet.ParcelData.SalePrice; 237 newData.salePrice = packet.ParcelData.SalePrice;
238 newData.snapshotID = packet.ParcelData.SnapshotID; 238 newData.snapshotID = packet.ParcelData.SnapshotID;
239 newData.userLocation = packet.ParcelData.UserLocation; 239 newData.userLocation = packet.ParcelData.UserLocation;
240 newData.userLookAt = packet.ParcelData.UserLookAt; 240 newData.userLookAt = packet.ParcelData.UserLookAt;
241 241
242 m_scene.LandChannel.updateLandObject(landData.localID, newData); 242 m_scene.LandChannel.updateLandObject(landData.localID, newData);
243 243
244 sendLandUpdateToAvatarsOverMe(); 244 sendLandUpdateToAvatarsOverMe();
245 } 245 }
246 } 246 }
247 247
248 public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 248 public void updateLandSold(LLUUID avatarID, LLUUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
249 { 249 {
250 LandData newData = landData.Copy(); 250 LandData newData = landData.Copy();
251 newData.ownerID = avatarID; 251 newData.ownerID = avatarID;
252 newData.groupID = groupID; 252 newData.groupID = groupID;
253 newData.isGroupOwned = groupOwned; 253 newData.isGroupOwned = groupOwned;
254 //newData.auctionID = AuctionID; 254 //newData.auctionID = AuctionID;
255 newData.claimDate = Util.UnixTimeSinceEpoch(); 255 newData.claimDate = Util.UnixTimeSinceEpoch();
256 newData.claimPrice = claimprice; 256 newData.claimPrice = claimprice;
257 newData.salePrice = 0; 257 newData.salePrice = 0;
258 newData.authBuyerID = LLUUID.Zero; 258 newData.authBuyerID = LLUUID.Zero;
259 newData.landFlags &= ~(uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects); 259 newData.landFlags &= ~(uint) (Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects);
260 m_scene.LandChannel.updateLandObject(landData.localID, newData); 260 m_scene.LandChannel.updateLandObject(landData.localID, newData);
261 261
262 sendLandUpdateToAvatarsOverMe(); 262 sendLandUpdateToAvatarsOverMe();
263 } 263 }
264 264
265 public bool isEitherBannedOrRestricted(LLUUID avatar) 265 public bool isEitherBannedOrRestricted(LLUUID avatar)
266 { 266 {
267 if (isBannedFromLand(avatar)) 267 if (isBannedFromLand(avatar))
268 { 268 {
269 return true; 269 return true;
270 } 270 }
271 else if (isRestrictedFromLand(avatar)) 271 else if (isRestrictedFromLand(avatar))
272 { 272 {
273 return true; 273 return true;
274 } 274 }
275 return false; 275 return false;
276 } 276 }
277 277
278 public bool isBannedFromLand(LLUUID avatar) 278 public bool isBannedFromLand(LLUUID avatar)
279 { 279 {
280 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0) 280 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0)
281 { 281 {
282 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 282 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
283 entry.AgentID = avatar; 283 entry.AgentID = avatar;
284 entry.Flags = ParcelManager.AccessList.Ban; 284 entry.Flags = ParcelManager.AccessList.Ban;
285 entry.Time = new DateTime(); 285 entry.Time = new DateTime();
286 if (landData.parcelAccessList.Contains(entry)) 286 if (landData.parcelAccessList.Contains(entry))
287 { 287 {
288 //They are banned, so lets send them a notice about this parcel 288 //They are banned, so lets send them a notice about this parcel
289 return true; 289 return true;
290 } 290 }
291 } 291 }
292 return false; 292 return false;
293 } 293 }
294 294
295 public bool isRestrictedFromLand(LLUUID avatar) 295 public bool isRestrictedFromLand(LLUUID avatar)
296 { 296 {
297 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0) 297 if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0)
298 { 298 {
299 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 299 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
300 entry.AgentID = avatar; 300 entry.AgentID = avatar;
301 entry.Flags = ParcelManager.AccessList.Access; 301 entry.Flags = ParcelManager.AccessList.Access;
302 entry.Time = new DateTime(); 302 entry.Time = new DateTime();
303 if (!landData.parcelAccessList.Contains(entry)) 303 if (!landData.parcelAccessList.Contains(entry))
304 { 304 {
305 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel 305 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
306 return true; 306 return true;
307 } 307 }
308 } 308 }
309 return false; 309 return false;
310 } 310 }
311 311
312 public void sendLandUpdateToClient(IClientAPI remote_client) 312 public void sendLandUpdateToClient(IClientAPI remote_client)
313 { 313 {
314 sendLandProperties(0, false, 0, remote_client); 314 sendLandProperties(0, false, 0, remote_client);
315 } 315 }
316 316
317 public void sendLandUpdateToAvatarsOverMe() 317 public void sendLandUpdateToAvatarsOverMe()
318 { 318 {
319 List<ScenePresence> avatars = m_scene.GetAvatars(); 319 List<ScenePresence> avatars = m_scene.GetAvatars();
320 ILandObject over = null; 320 ILandObject over = null;
321 for (int i = 0; i < avatars.Count; i++) 321 for (int i = 0; i < avatars.Count; i++)
322 { 322 {
323 try 323 try
324 { 324 {
325 over = 325 over =
326 m_scene.LandChannel.getLandObject((int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.X))), 326 m_scene.LandChannel.getLandObject((int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.X))),
327 (int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.Y)))); 327 (int) Math.Max(255, Math.Min(0, Math.Round(avatars[i].AbsolutePosition.Y))));
328 } 328 }
329 catch (Exception) 329 catch (Exception)
330 { 330 {
331 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + 331 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " +
332 Math.Round(avatars[i].AbsolutePosition.Y)); 332 Math.Round(avatars[i].AbsolutePosition.Y));
333 } 333 }
334 334
335 if (over != null) 335 if (over != null)
336 { 336 {
337 if (over.landData.localID == landData.localID) 337 if (over.landData.localID == landData.localID)
338 { 338 {
339 sendLandUpdateToClient(avatars[i].ControllingClient); 339 sendLandUpdateToClient(avatars[i].ControllingClient);
340 } 340 }
341 } 341 }
342 } 342 }
343 } 343 }
344 344
345 #endregion 345 #endregion
346 346
347 #region AccessList Functions 347 #region AccessList Functions
348 348
349 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag) 349 public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag)
350 { 350 {
351 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>(); 351 List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>();
352 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList) 352 foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList)
353 { 353 {
354 if (entry.Flags == flag) 354 if (entry.Flags == flag)
355 { 355 {
356 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); 356 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
357 357
358 listBlock.Flags = (uint) 0; 358 listBlock.Flags = (uint) 0;
359 listBlock.ID = entry.AgentID; 359 listBlock.ID = entry.AgentID;
360 listBlock.Time = 0; 360 listBlock.Time = 0;
361 361
362 list.Add(listBlock); 362 list.Add(listBlock);
363 } 363 }
364 } 364 }
365 365
366 if (list.Count == 0) 366 if (list.Count == 0)
367 { 367 {
368 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); 368 ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock();
369 369
370 listBlock.Flags = (uint) 0; 370 listBlock.Flags = (uint) 0;
371 listBlock.ID = LLUUID.Zero; 371 listBlock.ID = LLUUID.Zero;
372 listBlock.Time = 0; 372 listBlock.Time = 0;
373 373
374 list.Add(listBlock); 374 list.Add(listBlock);
375 } 375 }
376 return list.ToArray(); 376 return list.ToArray();
377 } 377 }
378 378
379 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, 379 public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID,
380 IClientAPI remote_client) 380 IClientAPI remote_client)
381 { 381 {
382 ParcelAccessListReplyPacket replyPacket; 382 ParcelAccessListReplyPacket replyPacket;
383 383
384 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both) 384 if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both)
385 { 385 {
386 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); 386 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
387 replyPacket.Data.AgentID = agentID; 387 replyPacket.Data.AgentID = agentID;
388 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access; 388 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access;
389 replyPacket.Data.LocalID = landData.localID; 389 replyPacket.Data.LocalID = landData.localID;
390 replyPacket.Data.SequenceID = 0; 390 replyPacket.Data.SequenceID = 0;
391 391
392 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access); 392 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access);
393 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); 393 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
394 } 394 }
395 395
396 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both) 396 if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both)
397 { 397 {
398 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); 398 replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply);
399 replyPacket.Data.AgentID = agentID; 399 replyPacket.Data.AgentID = agentID;
400 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban; 400 replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban;
401 replyPacket.Data.LocalID = landData.localID; 401 replyPacket.Data.LocalID = landData.localID;
402 replyPacket.Data.SequenceID = 0; 402 replyPacket.Data.SequenceID = 0;
403 403
404 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban); 404 replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban);
405 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); 405 remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task);
406 } 406 }
407 } 407 }
408 408
409 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) 409 public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
410 { 410 {
411 LandData newData = landData.Copy(); 411 LandData newData = landData.Copy();
412 412
413 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero) 413 if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero)
414 { 414 {
415 entries.Clear(); 415 entries.Clear();
416 } 416 }
417 417
418 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); 418 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
419 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList) 419 foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList)
420 { 420 {
421 if (entry.Flags == (ParcelManager.AccessList) flags) 421 if (entry.Flags == (ParcelManager.AccessList) flags)
422 { 422 {
423 toRemove.Add(entry); 423 toRemove.Add(entry);
424 } 424 }
425 } 425 }
426 426
427 foreach (ParcelManager.ParcelAccessEntry entry in toRemove) 427 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
428 { 428 {
429 newData.parcelAccessList.Remove(entry); 429 newData.parcelAccessList.Remove(entry);
430 } 430 }
431 foreach (ParcelManager.ParcelAccessEntry entry in entries) 431 foreach (ParcelManager.ParcelAccessEntry entry in entries)
432 { 432 {
433 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); 433 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
434 temp.AgentID = entry.AgentID; 434 temp.AgentID = entry.AgentID;
435 temp.Time = new DateTime(); //Pointless? Yes. 435 temp.Time = new DateTime(); //Pointless? Yes.
436 temp.Flags = (ParcelManager.AccessList) flags; 436 temp.Flags = (ParcelManager.AccessList) flags;
437 437
438 if (!newData.parcelAccessList.Contains(temp)) 438 if (!newData.parcelAccessList.Contains(temp))
439 { 439 {
440 newData.parcelAccessList.Add(temp); 440 newData.parcelAccessList.Add(temp);
441 } 441 }
442 } 442 }
443 443
444 m_scene.LandChannel.updateLandObject(landData.localID, newData); 444 m_scene.LandChannel.updateLandObject(landData.localID, newData);
445 } 445 }
446 446
447 #endregion 447 #endregion
448 448
449 #region Update Functions 449 #region Update Functions
450 450
451 public void updateLandBitmapByteArray() 451 public void updateLandBitmapByteArray()
452 { 452 {
453 landData.landBitmapByteArray = convertLandBitmapToBytes(); 453 landData.landBitmapByteArray = convertLandBitmapToBytes();
454 } 454 }
455 455
456 /// <summary> 456 /// <summary>
457 /// Update all settings in land such as area, bitmap byte array, etc 457 /// Update all settings in land such as area, bitmap byte array, etc
458 /// </summary> 458 /// </summary>
459 public void forceUpdateLandInfo() 459 public void forceUpdateLandInfo()
460 { 460 {
461 updateAABBAndAreaValues(); 461 updateAABBAndAreaValues();
462 updateLandBitmapByteArray(); 462 updateLandBitmapByteArray();
463 } 463 }
464 464
465 public void setLandBitmapFromByteArray() 465 public void setLandBitmapFromByteArray()
466 { 466 {
467 landBitmap = convertBytesToLandBitmap(); 467 landBitmap = convertBytesToLandBitmap();
468 } 468 }
469 469
470 /// <summary> 470 /// <summary>
471 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object 471 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
472 /// </summary> 472 /// </summary>
473 private void updateAABBAndAreaValues() 473 private void updateAABBAndAreaValues()
474 { 474 {
475 int min_x = 64; 475 int min_x = 64;
476 int min_y = 64; 476 int min_y = 64;
477 int max_x = 0; 477 int max_x = 0;
478 int max_y = 0; 478 int max_y = 0;
479 int tempArea = 0; 479 int tempArea = 0;
480 int x, y; 480 int x, y;
481 for (x = 0; x < 64; x++) 481 for (x = 0; x < 64; x++)
482 { 482 {
483 for (y = 0; y < 64; y++) 483 for (y = 0; y < 64; y++)
484 { 484 {
485 if (landBitmap[x, y] == true) 485 if (landBitmap[x, y] == true)
486 { 486 {
487 if (min_x > x) min_x = x; 487 if (min_x > x) min_x = x;
488 if (min_y > y) min_y = y; 488 if (min_y > y) min_y = y;
489 if (max_x < x) max_x = x; 489 if (max_x < x) max_x = x;
490 if (max_y < y) max_y = y; 490 if (max_y < y) max_y = y;
491 tempArea += 16; //16sqm peice of land 491 tempArea += 16; //16sqm peice of land
492 } 492 }
493 } 493 }
494 } 494 }
495 int tx = min_x * 4; 495 int tx = min_x * 4;
496 if (tx > 255) 496 if (tx > 255)
497 tx = 255; 497 tx = 255;
498 int ty = min_y * 4; 498 int ty = min_y * 4;
499 if (ty > 255) 499 if (ty > 255)
500 ty = 255; 500 ty = 255;
501 landData.AABBMin = 501 landData.AABBMin =
502 new LLVector3((float) (min_x * 4), (float) (min_y * 4), 502 new LLVector3((float) (min_x * 4), (float) (min_y * 4),
503 (float) m_scene.Heightmap[tx, ty]); 503 (float) m_scene.Heightmap[tx, ty]);
504 504
505 tx = max_x * 4; 505 tx = max_x * 4;
506 if (tx > 255) 506 if (tx > 255)
507 tx = 255; 507 tx = 255;
508 ty = max_y * 4; 508 ty = max_y * 4;
509 if (ty > 255) 509 if (ty > 255)
510 ty = 255; 510 ty = 255;
511 landData.AABBMax = 511 landData.AABBMax =
512 new LLVector3((float) (max_x * 4), (float) (max_y * 4), 512 new LLVector3((float) (max_x * 4), (float) (max_y * 4),
513 (float) m_scene.Heightmap[tx, ty]); 513 (float) m_scene.Heightmap[tx, ty]);
514 landData.area = tempArea; 514 landData.area = tempArea;
515 } 515 }
516 516
517 #endregion 517 #endregion
518 518
519 #region Land Bitmap Functions 519 #region Land Bitmap Functions
520 520
521 /// <summary> 521 /// <summary>
522 /// Sets the land's bitmap manually 522 /// Sets the land's bitmap manually
523 /// </summary> 523 /// </summary>
524 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 524 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
525 public void setLandBitmap(bool[,] bitmap) 525 public void setLandBitmap(bool[,] bitmap)
526 { 526 {
527 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 527 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
528 { 528 {
529 //Throw an exception - The bitmap is not 64x64 529 //Throw an exception - The bitmap is not 64x64
530 //throw new Exception("Error: Invalid Parcel Bitmap"); 530 //throw new Exception("Error: Invalid Parcel Bitmap");
531 } 531 }
532 else 532 else
533 { 533 {
534 //Valid: Lets set it 534 //Valid: Lets set it
535 landBitmap = bitmap; 535 landBitmap = bitmap;
536 forceUpdateLandInfo(); 536 forceUpdateLandInfo();
537 } 537 }
538 } 538 }
539 539
540 /// <summary> 540 /// <summary>
541 /// Gets the land's bitmap manually 541 /// Gets the land's bitmap manually
542 /// </summary> 542 /// </summary>
543 /// <returns></returns> 543 /// <returns></returns>
544 public bool[,] getLandBitmap() 544 public bool[,] getLandBitmap()
545 { 545 {
546 return landBitmap; 546 return landBitmap;
547 } 547 }
548 548
549 /// <summary> 549 /// <summary>
550 /// Full sim land object creation 550 /// Full sim land object creation
551 /// </summary> 551 /// </summary>
552 /// <returns></returns> 552 /// <returns></returns>
553 public bool[,] basicFullRegionLandBitmap() 553 public bool[,] basicFullRegionLandBitmap()
554 { 554 {
555 return getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 555 return getSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
556 } 556 }
557 557
558 /// <summary> 558 /// <summary>
559 /// Used to modify the bitmap between the x and y points. Points use 64 scale 559 /// Used to modify the bitmap between the x and y points. Points use 64 scale
560 /// </summary> 560 /// </summary>
561 /// <param name="start_x"></param> 561 /// <param name="start_x"></param>
562 /// <param name="start_y"></param> 562 /// <param name="start_y"></param>
563 /// <param name="end_x"></param> 563 /// <param name="end_x"></param>
564 /// <param name="end_y"></param> 564 /// <param name="end_y"></param>
565 /// <returns></returns> 565 /// <returns></returns>
566 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 566 public bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
567 { 567 {
568 bool[,] tempBitmap = new bool[64,64]; 568 bool[,] tempBitmap = new bool[64,64];
569 tempBitmap.Initialize(); 569 tempBitmap.Initialize();
570 570
571 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 571 tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
572 return tempBitmap; 572 return tempBitmap;
573 } 573 }
574 574
575 /// <summary> 575 /// <summary>
576 /// Change a land bitmap at within a square and set those points to a specific value 576 /// Change a land bitmap at within a square and set those points to a specific value
577 /// </summary> 577 /// </summary>
578 /// <param name="land_bitmap"></param> 578 /// <param name="land_bitmap"></param>
579 /// <param name="start_x"></param> 579 /// <param name="start_x"></param>
580 /// <param name="start_y"></param> 580 /// <param name="start_y"></param>
581 /// <param name="end_x"></param> 581 /// <param name="end_x"></param>
582 /// <param name="end_y"></param> 582 /// <param name="end_y"></param>
583 /// <param name="set_value"></param> 583 /// <param name="set_value"></param>
584 /// <returns></returns> 584 /// <returns></returns>
585 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 585 public bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
586 bool set_value) 586 bool set_value)
587 { 587 {
588 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) 588 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
589 { 589 {
590 //Throw an exception - The bitmap is not 64x64 590 //Throw an exception - The bitmap is not 64x64
591 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); 591 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
592 } 592 }
593 593
594 int x, y; 594 int x, y;
595 for (y = 0; y < 64; y++) 595 for (y = 0; y < 64; y++)
596 { 596 {
597 for (x = 0; x < 64; x++) 597 for (x = 0; x < 64; x++)
598 { 598 {
599 if (x >= start_x / 4 && x < end_x / 4 599 if (x >= start_x / 4 && x < end_x / 4
600 && y >= start_y / 4 && y < end_y / 4) 600 && y >= start_y / 4 && y < end_y / 4)
601 { 601 {
602 land_bitmap[x, y] = set_value; 602 land_bitmap[x, y] = set_value;
603 } 603 }
604 } 604 }
605 } 605 }
606 return land_bitmap; 606 return land_bitmap;
607 } 607 }
608 608
609 /// <summary> 609 /// <summary>
610 /// Join the true values of 2 bitmaps together 610 /// Join the true values of 2 bitmaps together
611 /// </summary> 611 /// </summary>
612 /// <param name="bitmap_base"></param> 612 /// <param name="bitmap_base"></param>
613 /// <param name="bitmap_add"></param> 613 /// <param name="bitmap_add"></param>
614 /// <returns></returns> 614 /// <returns></returns>
615 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 615 public bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
616 { 616 {
617 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 617 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
618 { 618 {
619 //Throw an exception - The bitmap is not 64x64 619 //Throw an exception - The bitmap is not 64x64
620 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 620 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
621 } 621 }
622 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 622 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
623 { 623 {
624 //Throw an exception - The bitmap is not 64x64 624 //Throw an exception - The bitmap is not 64x64
625 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); 625 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
626 } 626 }
627 627
628 int x, y; 628 int x, y;
629 for (y = 0; y < 64; y++) 629 for (y = 0; y < 64; y++)
630 { 630 {
631 for (x = 0; x < 64; x++) 631 for (x = 0; x < 64; x++)
632 { 632 {
633 if (bitmap_add[x, y]) 633 if (bitmap_add[x, y])
634 { 634 {
635 bitmap_base[x, y] = true; 635 bitmap_base[x, y] = true;
636 } 636 }
637 } 637 }
638 } 638 }
639 return bitmap_base; 639 return bitmap_base;
640 } 640 }
641 641
642 /// <summary> 642 /// <summary>
643 /// Converts the land bitmap to a packet friendly byte array 643 /// Converts the land bitmap to a packet friendly byte array
644 /// </summary> 644 /// </summary>
645 /// <returns></returns> 645 /// <returns></returns>
646 private byte[] convertLandBitmapToBytes() 646 private byte[] convertLandBitmapToBytes()
647 { 647 {
648 byte[] tempConvertArr = new byte[512]; 648 byte[] tempConvertArr = new byte[512];
649 byte tempByte = 0; 649 byte tempByte = 0;
650 int x, y, i, byteNum = 0; 650 int x, y, i, byteNum = 0;
651 i = 0; 651 i = 0;
652 for (y = 0; y < 64; y++) 652 for (y = 0; y < 64; y++)
653 { 653 {
654 for (x = 0; x < 64; x++) 654 for (x = 0; x < 64; x++)
655 { 655 {
656 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8)); 656 tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8));
657 if (i % 8 == 0) 657 if (i % 8 == 0)
658 { 658 {
659 tempConvertArr[byteNum] = tempByte; 659 tempConvertArr[byteNum] = tempByte;
660 tempByte = (byte) 0; 660 tempByte = (byte) 0;
661 i = 0; 661 i = 0;
662 byteNum++; 662 byteNum++;
663 } 663 }
664 } 664 }
665 } 665 }
666 return tempConvertArr; 666 return tempConvertArr;
667 } 667 }
668 668
669 private bool[,] convertBytesToLandBitmap() 669 private bool[,] convertBytesToLandBitmap()
670 { 670 {
671 bool[,] tempConvertMap = new bool[64,64]; 671 bool[,] tempConvertMap = new bool[64,64];
672 tempConvertMap.Initialize(); 672 tempConvertMap.Initialize();
673 byte tempByte = 0; 673 byte tempByte = 0;
674 int x = 0, y = 0, i = 0, bitNum = 0; 674 int x = 0, y = 0, i = 0, bitNum = 0;
675 for (i = 0; i < 512; i++) 675 for (i = 0; i < 512; i++)
676 { 676 {
677 tempByte = landData.landBitmapByteArray[i]; 677 tempByte = landData.landBitmapByteArray[i];
678 for (bitNum = 0; bitNum < 8; bitNum++) 678 for (bitNum = 0; bitNum < 8; bitNum++)
679 { 679 {
680 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 680 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
681 tempConvertMap[x, y] = bit; 681 tempConvertMap[x, y] = bit;
682 x++; 682 x++;
683 if (x > 63) 683 if (x > 63)
684 { 684 {
685 x = 0; 685 x = 0;
686 y++; 686 y++;
687 } 687 }
688 } 688 }
689 } 689 }
690 return tempConvertMap; 690 return tempConvertMap;
691 } 691 }
692 692
693 #endregion 693 #endregion
694 694
695 #region Object Select and Object Owner Listing 695 #region Object Select and Object Owner Listing
696 696
697 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) 697 public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client)
698 { 698 {
699 List<uint> resultLocalIDs = new List<uint>(); 699 List<uint> resultLocalIDs = new List<uint>();
700 foreach (SceneObjectGroup obj in primsOverMe) 700 foreach (SceneObjectGroup obj in primsOverMe)
701 { 701 {
702 if (obj.LocalId > 0) 702 if (obj.LocalId > 0)
703 { 703 {
704 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID) 704 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID)
705 { 705 {
706 resultLocalIDs.Add(obj.LocalId); 706 resultLocalIDs.Add(obj.LocalId);
707 } 707 }
708 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support 708 // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support
709 // { 709 // {
710 // } 710 // }
711 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && 711 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
712 obj.OwnerID != remote_client.AgentId) 712 obj.OwnerID != remote_client.AgentId)
713 { 713 {
714 resultLocalIDs.Add(obj.LocalId); 714 resultLocalIDs.Add(obj.LocalId);
715 } 715 }
716 } 716 }
717 } 717 }
718 718
719 719
720 bool firstCall = true; 720 bool firstCall = true;
721 int MAX_OBJECTS_PER_PACKET = 251; 721 int MAX_OBJECTS_PER_PACKET = 251;
722 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); 722 ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect);
723 // TODO: don't create new blocks if recycling an old packet 723 // TODO: don't create new blocks if recycling an old packet
724 ForceObjectSelectPacket.DataBlock[] data; 724 ForceObjectSelectPacket.DataBlock[] data;
725 while (resultLocalIDs.Count > 0) 725 while (resultLocalIDs.Count > 0)
726 { 726 {
727 if (firstCall) 727 if (firstCall)
728 { 728 {
729 pack._Header.ResetList = true; 729 pack._Header.ResetList = true;
730 firstCall = false; 730 firstCall = false;
731 } 731 }
732 else 732 else
733 { 733 {
734 pack._Header.ResetList = false; 734 pack._Header.ResetList = false;
735 } 735 }
736 736
737 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) 737 if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET)
738 { 738 {
739 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; 739 data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET];
740 } 740 }
741 else 741 else
742 { 742 {
743 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; 743 data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count];
744 } 744 }
745 745
746 int i; 746 int i;
747 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) 747 for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++)
748 { 748 {
749 data[i] = new ForceObjectSelectPacket.DataBlock(); 749 data[i] = new ForceObjectSelectPacket.DataBlock();
750 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); 750 data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]);
751 resultLocalIDs.RemoveAt(0); 751 resultLocalIDs.RemoveAt(0);
752 } 752 }
753 pack.Data = data; 753 pack.Data = data;
754 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task); 754 remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task);
755 } 755 }
756 } 756 }
757 757
758 /// <summary> 758 /// <summary>
759 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes 759 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
760 /// aggreagete details such as the number of prims. 760 /// aggreagete details such as the number of prims.
761 /// 761 ///
762 /// </summary> 762 /// </summary>
763 /// <param name="remote_client"> 763 /// <param name="remote_client">
764 /// A <see cref="IClientAPI"/> 764 /// A <see cref="IClientAPI"/>
765 /// </param> 765 /// </param>
766 public void sendLandObjectOwners(IClientAPI remote_client) 766 public void sendLandObjectOwners(IClientAPI remote_client)
767 { 767 {
768 Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>(); 768 Dictionary<LLUUID, int> primCount = new Dictionary<LLUUID, int>();
769 ParcelObjectOwnersReplyPacket pack 769 ParcelObjectOwnersReplyPacket pack
770 = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); 770 = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
771 // TODO: don't create new blocks if recycling an old packet 771 // TODO: don't create new blocks if recycling an old packet
772 772
773 foreach (SceneObjectGroup obj in primsOverMe) 773 foreach (SceneObjectGroup obj in primsOverMe)
774 { 774 {
775 try 775 try
776 { 776 {
777 if (!primCount.ContainsKey(obj.OwnerID)) 777 if (!primCount.ContainsKey(obj.OwnerID))
778 { 778 {
779 primCount.Add(obj.OwnerID, 0); 779 primCount.Add(obj.OwnerID, 0);
780 } 780 }
781 } 781 }
782 catch (NullReferenceException) 782 catch (NullReferenceException)
783 { 783 {
784 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); 784 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
785 } 785 }
786 try 786 try
787 { 787 {
788 primCount[obj.OwnerID] += obj.PrimCount; 788 primCount[obj.OwnerID] += obj.PrimCount;
789 } 789 }
790 catch (KeyNotFoundException) 790 catch (KeyNotFoundException)
791 { 791 {
792 m_log.Error("[LAND]: Unable to match a prim with it's owner."); 792 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
793 } 793 }
794 } 794 }
795 795
796 int notifyCount = primCount.Count; 796 int notifyCount = primCount.Count;
797 797
798 if (notifyCount > 0) 798 if (notifyCount > 0)
799 { 799 {
800 if (notifyCount > 32) 800 if (notifyCount > 32)
801 { 801 {
802 m_log.InfoFormat( 802 m_log.InfoFormat(
803 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 803 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
804 + " - a developer might want to investigate whether this is a hard limit", 32); 804 + " - a developer might want to investigate whether this is a hard limit", 32);
805 805
806 notifyCount = 32; 806 notifyCount = 32;
807 } 807 }
808 808
809 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 809 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
810 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 810 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
811 811
812 int num = 0; 812 int num = 0;
813 foreach (LLUUID owner in primCount.Keys) 813 foreach (LLUUID owner in primCount.Keys)
814 { 814 {
815 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); 815 dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock();
816 dataBlock[num].Count = primCount[owner]; 816 dataBlock[num].Count = primCount[owner];
817 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added 817 dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added
818 dataBlock[num].OnlineStatus = true; //TODO: fix me later 818 dataBlock[num].OnlineStatus = true; //TODO: fix me later
819 dataBlock[num].OwnerID = owner; 819 dataBlock[num].OwnerID = owner;
820 820
821 num++; 821 num++;
822 822
823 if (num >= notifyCount) 823 if (num >= notifyCount)
824 { 824 {
825 break; 825 break;
826 } 826 }
827 } 827 }
828 828
829 pack.Data = dataBlock; 829 pack.Data = dataBlock;
830 } 830 }
831 831
832 remote_client.OutPacket(pack, ThrottleOutPacketType.Task); 832 remote_client.OutPacket(pack, ThrottleOutPacketType.Task);
833 } 833 }
834 834
835 public Dictionary<LLUUID, int> getLandObjectOwners() 835 public Dictionary<LLUUID, int> getLandObjectOwners()
836 { 836 {
837 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>(); 837 Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>();
838 foreach (SceneObjectGroup obj in primsOverMe) 838 foreach (SceneObjectGroup obj in primsOverMe)
839 { 839 {
840 if (!ownersAndCount.ContainsKey(obj.OwnerID)) 840 if (!ownersAndCount.ContainsKey(obj.OwnerID))
841 { 841 {
842 ownersAndCount.Add(obj.OwnerID, 0); 842 ownersAndCount.Add(obj.OwnerID, 0);
843 } 843 }
844 ownersAndCount[obj.OwnerID] += obj.PrimCount; 844 ownersAndCount[obj.OwnerID] += obj.PrimCount;
845 } 845 }
846 return ownersAndCount; 846 return ownersAndCount;
847 } 847 }
848 848
849 #endregion 849 #endregion
850 850
851 #region Object Returning 851 #region Object Returning
852 852
853 public void returnObject(SceneObjectGroup obj) 853 public void returnObject(SceneObjectGroup obj)
854 { 854 {
855 } 855 }
856 856
857 public void returnLandObjects(int type, LLUUID owner) 857 public void returnLandObjects(int type, LLUUID owner)
858 { 858 {
859 } 859 }
860 860
861 #endregion 861 #endregion
862 862
863 #region Object Adding/Removing from Parcel 863 #region Object Adding/Removing from Parcel
864 864
865 public void resetLandPrimCounts() 865 public void resetLandPrimCounts()
866 { 866 {
867 landData.groupPrims = 0; 867 landData.groupPrims = 0;
868 landData.ownerPrims = 0; 868 landData.ownerPrims = 0;
869 landData.otherPrims = 0; 869 landData.otherPrims = 0;
870 landData.selectedPrims = 0; 870 landData.selectedPrims = 0;
871 primsOverMe.Clear(); 871 primsOverMe.Clear();
872 } 872 }
873 873
874 public void addPrimToCount(SceneObjectGroup obj) 874 public void addPrimToCount(SceneObjectGroup obj)
875 { 875 {
876 LLUUID prim_owner = obj.OwnerID; 876 LLUUID prim_owner = obj.OwnerID;
877 int prim_count = obj.PrimCount; 877 int prim_count = obj.PrimCount;
878 878
879 if (obj.IsSelected) 879 if (obj.IsSelected)
880 { 880 {
881 landData.selectedPrims += prim_count; 881 landData.selectedPrims += prim_count;
882 } 882 }
883 else 883 else
884 { 884 {
885 if (prim_owner == landData.ownerID) 885 if (prim_owner == landData.ownerID)
886 { 886 {
887 landData.ownerPrims += prim_count; 887 landData.ownerPrims += prim_count;
888 } 888 }
889 else 889 else
890 { 890 {
891 landData.otherPrims += prim_count; 891 landData.otherPrims += prim_count;
892 } 892 }
893 } 893 }
894 894
895 primsOverMe.Add(obj); 895 primsOverMe.Add(obj);
896 } 896 }
897 897
898 public void removePrimFromCount(SceneObjectGroup obj) 898 public void removePrimFromCount(SceneObjectGroup obj)
899 { 899 {
900 if (primsOverMe.Contains(obj)) 900 if (primsOverMe.Contains(obj))
901 { 901 {
902 LLUUID prim_owner = obj.OwnerID; 902 LLUUID prim_owner = obj.OwnerID;
903 int prim_count = obj.PrimCount; 903 int prim_count = obj.PrimCount;
904 904
905 if (prim_owner == landData.ownerID) 905 if (prim_owner == landData.ownerID)
906 { 906 {
907 landData.ownerPrims -= prim_count; 907 landData.ownerPrims -= prim_count;
908 } 908 }
909 else if (prim_owner == landData.groupID) 909 else if (prim_owner == landData.groupID)
910 { 910 {
911 landData.groupPrims -= prim_count; 911 landData.groupPrims -= prim_count;
912 } 912 }
913 else 913 else
914 { 914 {
915 landData.otherPrims -= prim_count; 915 landData.otherPrims -= prim_count;
916 } 916 }
917 917
918 primsOverMe.Remove(obj); 918 primsOverMe.Remove(obj);
919 } 919 }
920 } 920 }
921 921
922 #endregion 922 #endregion
923 923
924 #endregion 924 #endregion
925 925
926 #endregion 926 #endregion
927 } 927 }
928} \ No newline at end of file 928} \ No newline at end of file