diff options
Diffstat (limited to 'OpenSim/Region/Environment/LandManagement/LandManager.cs')
-rw-r--r-- | OpenSim/Region/Environment/LandManagement/LandManager.cs | 1234 |
1 files changed, 617 insertions, 617 deletions
diff --git a/OpenSim/Region/Environment/LandManagement/LandManager.cs b/OpenSim/Region/Environment/LandManagement/LandManager.cs index 8c359fc..f759934 100644 --- a/OpenSim/Region/Environment/LandManagement/LandManager.cs +++ b/OpenSim/Region/Environment/LandManagement/LandManager.cs | |||
@@ -1,617 +1,617 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://www.openmetaverse.org/ | 2 | * Copyright (c) Contributors, http://www.openmetaverse.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 | */ |
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using libsecondlife.Packets; | 31 | using libsecondlife.Packets; |
32 | using OpenSim.Framework.Interfaces; | 32 | using OpenSim.Framework.Interfaces; |
33 | using OpenSim.Framework.Types; | 33 | using OpenSim.Framework.Types; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | using OpenSim.Region.Environment.Scenes; |
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.LandManagement | 36 | namespace OpenSim.Region.Environment.LandManagement |
37 | { | 37 | { |
38 | 38 | ||
39 | 39 | ||
40 | #region LandManager Class | 40 | #region LandManager Class |
41 | /// <summary> | 41 | /// <summary> |
42 | /// Handles Land objects and operations requiring information from other Land objects (divide, join, etc) | 42 | /// Handles Land objects and operations requiring information from other Land objects (divide, join, etc) |
43 | /// </summary> | 43 | /// </summary> |
44 | public class LandManager : ILocalStorageLandObjectReceiver | 44 | public class LandManager : ILocalStorageLandObjectReceiver |
45 | { | 45 | { |
46 | 46 | ||
47 | #region Constants | 47 | #region Constants |
48 | //Land types set with flags in ParcelOverlay. | 48 | //Land types set with flags in ParcelOverlay. |
49 | //Only one of these can be used. | 49 | //Only one of these can be used. |
50 | public const byte LAND_TYPE_PUBLIC = (byte)0; //Equals 00000000 | 50 | public const byte LAND_TYPE_PUBLIC = (byte)0; //Equals 00000000 |
51 | public const byte LAND_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 | 51 | public const byte LAND_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 |
52 | public const byte LAND_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 | 52 | public const byte LAND_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 |
53 | public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 | 53 | public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 |
54 | public const byte LAND_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 | 54 | public const byte LAND_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 |
55 | public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 | 55 | public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 |
56 | 56 | ||
57 | 57 | ||
58 | //Flags that when set, a border on the given side will be placed | 58 | //Flags that when set, a border on the given side will be placed |
59 | //NOTE: North and East is assumable by the west and south sides (if land to east has a west border, then I have an east border; etc) | 59 | //NOTE: North and East is assumable by the west and south sides (if land to east has a west border, then I have an east border; etc) |
60 | //This took forever to figure out -- jeesh. /blame LL for even having to send these | 60 | //This took forever to figure out -- jeesh. /blame LL for even having to send these |
61 | public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 | 61 | public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 |
62 | public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 | 62 | public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 |
63 | 63 | ||
64 | //RequestResults (I think these are right, they seem to work): | 64 | //RequestResults (I think these are right, they seem to work): |
65 | public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land | 65 | public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land |
66 | public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land | 66 | public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land |
67 | 67 | ||
68 | //ParcelSelectObjects | 68 | //ParcelSelectObjects |
69 | public const int LAND_SELECT_OBJECTS_OWNER = 2; | 69 | public const int LAND_SELECT_OBJECTS_OWNER = 2; |
70 | public const int LAND_SELECT_OBJECTS_GROUP = 4; | 70 | public const int LAND_SELECT_OBJECTS_GROUP = 4; |
71 | public const int LAND_SELECT_OBJECTS_OTHER = 8; | 71 | public const int LAND_SELECT_OBJECTS_OTHER = 8; |
72 | 72 | ||
73 | 73 | ||
74 | //These are other constants. Yay! | 74 | //These are other constants. Yay! |
75 | public const int START_LAND_LOCAL_ID = 1; | 75 | public const int START_LAND_LOCAL_ID = 1; |
76 | #endregion | 76 | #endregion |
77 | 77 | ||
78 | #region Member Variables | 78 | #region Member Variables |
79 | public Dictionary<int, Land> landList = new Dictionary<int, Land>(); | 79 | public Dictionary<int, Land> landList = new Dictionary<int, Land>(); |
80 | private int lastLandLocalID = START_LAND_LOCAL_ID - 1; | 80 | private int lastLandLocalID = START_LAND_LOCAL_ID - 1; |
81 | private int[,] landIDList = new int[64, 64]; | 81 | private int[,] landIDList = new int[64, 64]; |
82 | 82 | ||
83 | /// <summary> | 83 | /// <summary> |
84 | /// Set to true when a prim is moved, created, added. Performs a prim count update | 84 | /// Set to true when a prim is moved, created, added. Performs a prim count update |
85 | /// </summary> | 85 | /// </summary> |
86 | public bool landPrimCountTainted = false; | 86 | public bool landPrimCountTainted = false; |
87 | 87 | ||
88 | private Scene m_scene; | 88 | private Scene m_scene; |
89 | private RegionInfo m_regInfo; | 89 | private RegionInfo m_regInfo; |
90 | 90 | ||
91 | #endregion | 91 | #endregion |
92 | 92 | ||
93 | #region Constructors | 93 | #region Constructors |
94 | public LandManager(Scene scene, RegionInfo reginfo) | 94 | public LandManager(Scene scene, RegionInfo reginfo) |
95 | { | 95 | { |
96 | 96 | ||
97 | m_scene = scene; | 97 | m_scene = scene; |
98 | m_regInfo = reginfo; | 98 | m_regInfo = reginfo; |
99 | landIDList.Initialize(); | 99 | landIDList.Initialize(); |
100 | 100 | ||
101 | } | 101 | } |
102 | #endregion | 102 | #endregion |
103 | 103 | ||
104 | #region Member Functions | 104 | #region Member Functions |
105 | 105 | ||
106 | #region Parcel From Storage Functions | 106 | #region Parcel From Storage Functions |
107 | public void LandFromStorage(LandData data) | 107 | public void LandFromStorage(LandData data) |
108 | { | 108 | { |
109 | Land new_land = new Land(data.ownerID, data.isGroupOwned, m_scene); | 109 | Land new_land = new Land(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 | 115 | ||
116 | public void NoLandDataFromStorage() | 116 | public void NoLandDataFromStorage() |
117 | { | 117 | { |
118 | resetSimLandObjects(); | 118 | resetSimLandObjects(); |
119 | } | 119 | } |
120 | #endregion | 120 | #endregion |
121 | 121 | ||
122 | #region Parcel Add/Remove/Get/Create | 122 | #region Parcel Add/Remove/Get/Create |
123 | /// <summary> | 123 | /// <summary> |
124 | /// Creates a basic Parcel object without an owner (a zeroed key) | 124 | /// Creates a basic Parcel object without an owner (a zeroed key) |
125 | /// </summary> | 125 | /// </summary> |
126 | /// <returns></returns> | 126 | /// <returns></returns> |
127 | public Land createBaseLand() | 127 | public Land createBaseLand() |
128 | { | 128 | { |
129 | return new Land(new LLUUID(), false, m_scene); | 129 | return new Land(new LLUUID(), false, m_scene); |
130 | } | 130 | } |
131 | 131 | ||
132 | /// <summary> | 132 | /// <summary> |
133 | /// Adds a land object to the stored list and adds them to the landIDList to what they own | 133 | /// Adds a land object to the stored list and adds them to the landIDList to what they own |
134 | /// </summary> | 134 | /// </summary> |
135 | /// <param name="new_land">The land object being added</param> | 135 | /// <param name="new_land">The land object being added</param> |
136 | public Land addLandObject(Land new_land) | 136 | public Land addLandObject(Land new_land) |
137 | { | 137 | { |
138 | lastLandLocalID++; | 138 | lastLandLocalID++; |
139 | new_land.landData.localID = lastLandLocalID; | 139 | new_land.landData.localID = lastLandLocalID; |
140 | landList.Add(lastLandLocalID, new_land.Copy()); | 140 | landList.Add(lastLandLocalID, new_land.Copy()); |
141 | 141 | ||
142 | 142 | ||
143 | bool[,] landBitmap = new_land.getLandBitmap(); | 143 | bool[,] landBitmap = new_land.getLandBitmap(); |
144 | int x, y; | 144 | int x, y; |
145 | for (x = 0; x < 64; x++) | 145 | for (x = 0; x < 64; x++) |
146 | { | 146 | { |
147 | for (y = 0; y < 64; y++) | 147 | for (y = 0; y < 64; y++) |
148 | { | 148 | { |
149 | if (landBitmap[x, y]) | 149 | if (landBitmap[x, y]) |
150 | { | 150 | { |
151 | landIDList[x, y] = lastLandLocalID; | 151 | landIDList[x, y] = lastLandLocalID; |
152 | } | 152 | } |
153 | } | 153 | } |
154 | } | 154 | } |
155 | landList[lastLandLocalID].forceUpdateLandInfo(); | 155 | landList[lastLandLocalID].forceUpdateLandInfo(); |
156 | 156 | ||
157 | return new_land; | 157 | return new_land; |
158 | 158 | ||
159 | } | 159 | } |
160 | /// <summary> | 160 | /// <summary> |
161 | /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList | 161 | /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList |
162 | /// </summary> | 162 | /// </summary> |
163 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> | 163 | /// <param name="local_id">Land.localID of the peice of land to remove.</param> |
164 | public void removeLandObject(int local_id) | 164 | public void removeLandObject(int local_id) |
165 | { | 165 | { |
166 | int x, y; | 166 | int x, y; |
167 | for (x = 0; x < 64; x++) | 167 | for (x = 0; x < 64; x++) |
168 | { | 168 | { |
169 | for (y = 0; y < 64; y++) | 169 | for (y = 0; y < 64; y++) |
170 | { | 170 | { |
171 | if (landIDList[x, y] == local_id) | 171 | if (landIDList[x, y] == local_id) |
172 | { | 172 | { |
173 | throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); | 173 | throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); |
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | // TODO: Put event here for storage manager to bind to. | 177 | // TODO: Put event here for storage manager to bind to. |
178 | landList.Remove(local_id); | 178 | landList.Remove(local_id); |
179 | } | 179 | } |
180 | 180 | ||
181 | private void performFinalLandJoin(Land master, Land slave) | 181 | private void performFinalLandJoin(Land master, Land slave) |
182 | { | 182 | { |
183 | int x, y; | 183 | int x, y; |
184 | bool[,] landBitmapSlave = slave.getLandBitmap(); | 184 | bool[,] landBitmapSlave = slave.getLandBitmap(); |
185 | for (x = 0; x < 64; x++) | 185 | for (x = 0; x < 64; x++) |
186 | { | 186 | { |
187 | for (y = 0; y < 64; y++) | 187 | for (y = 0; y < 64; y++) |
188 | { | 188 | { |
189 | if (landBitmapSlave[x, y]) | 189 | if (landBitmapSlave[x, y]) |
190 | { | 190 | { |
191 | landIDList[x, y] = master.landData.localID; | 191 | landIDList[x, y] = master.landData.localID; |
192 | } | 192 | } |
193 | } | 193 | } |
194 | } | 194 | } |
195 | removeLandObject(slave.landData.localID); | 195 | removeLandObject(slave.landData.localID); |
196 | } | 196 | } |
197 | /// <summary> | 197 | /// <summary> |
198 | /// Get the land object at the specified point | 198 | /// Get the land object at the specified point |
199 | /// </summary> | 199 | /// </summary> |
200 | /// <param name="x">Value between 0 - 256 on the x axis of the point</param> | 200 | /// <param name="x">Value between 0 - 256 on the x axis of the point</param> |
201 | /// <param name="y">Value between 0 - 256 on the y axis of the point</param> | 201 | /// <param name="y">Value between 0 - 256 on the y axis of the point</param> |
202 | /// <returns>Land object at the point supplied</returns> | 202 | /// <returns>Land object at the point supplied</returns> |
203 | public Land getLandObject(float x_float, float y_float) | 203 | public Land getLandObject(float x_float, float y_float) |
204 | { | 204 | { |
205 | int x = Convert.ToInt32(Math.Floor(Convert.ToDecimal(x_float) / Convert.ToDecimal(4.0))); | 205 | int x = Convert.ToInt32(Math.Floor(Convert.ToDecimal(x_float) / Convert.ToDecimal(4.0))); |
206 | int y = Convert.ToInt32(Math.Floor(Convert.ToDecimal(y_float) / Convert.ToDecimal(4.0))); | 206 | int y = Convert.ToInt32(Math.Floor(Convert.ToDecimal(y_float) / Convert.ToDecimal(4.0))); |
207 | 207 | ||
208 | if (x > 63 || y > 63 || x < 0 || y < 0) | 208 | if (x > 63 || y > 63 || x < 0 || y < 0) |
209 | { | 209 | { |
210 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 210 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); |
211 | } | 211 | } |
212 | else | 212 | else |
213 | { | 213 | { |
214 | // Console.WriteLine("Point (" + x + ", " + y + ") determined from point (" + x_float + ", " + y_float + ")"); | 214 | // Console.WriteLine("Point (" + x + ", " + y + ") determined from point (" + x_float + ", " + y_float + ")"); |
215 | return landList[landIDList[x, y]]; | 215 | return landList[landIDList[x, y]]; |
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
219 | public Land getLandObject(int x, int y) | 219 | public Land getLandObject(int x, int y) |
220 | { | 220 | { |
221 | if (x > 256 || y > 256 || x < 0 || y < 0) | 221 | if (x > 256 || y > 256 || x < 0 || y < 0) |
222 | { | 222 | { |
223 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 223 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); |
224 | } | 224 | } |
225 | else | 225 | else |
226 | { | 226 | { |
227 | return landList[landIDList[x / 4, y / 4]]; | 227 | return landList[landIDList[x / 4, y / 4]]; |
228 | } | 228 | } |
229 | } | 229 | } |
230 | #endregion | 230 | #endregion |
231 | 231 | ||
232 | #region Parcel Modification | 232 | #region Parcel Modification |
233 | /// <summary> | 233 | /// <summary> |
234 | /// Subdivides a piece of land | 234 | /// Subdivides a piece of land |
235 | /// </summary> | 235 | /// </summary> |
236 | /// <param name="start_x">West Point</param> | 236 | /// <param name="start_x">West Point</param> |
237 | /// <param name="start_y">South Point</param> | 237 | /// <param name="start_y">South Point</param> |
238 | /// <param name="end_x">East Point</param> | 238 | /// <param name="end_x">East Point</param> |
239 | /// <param name="end_y">North Point</param> | 239 | /// <param name="end_y">North Point</param> |
240 | /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> | 240 | /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> |
241 | /// <returns>Returns true if successful</returns> | 241 | /// <returns>Returns true if successful</returns> |
242 | private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 242 | private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
243 | { | 243 | { |
244 | 244 | ||
245 | //First, lets loop through the points and make sure they are all in the same peice of land | 245 | //First, lets loop through the points and make sure they are all in the same peice of land |
246 | //Get the land object at start | 246 | //Get the land object at start |
247 | Land startLandObject = getLandObject(start_x, start_y); | 247 | Land startLandObject = getLandObject(start_x, start_y); |
248 | if (startLandObject == null) return false; //No such land object at the beginning | 248 | if (startLandObject == null) return false; //No such land object at the beginning |
249 | 249 | ||
250 | //Loop through the points | 250 | //Loop through the points |
251 | try | 251 | try |
252 | { | 252 | { |
253 | int totalX = end_x - start_x; | 253 | int totalX = end_x - start_x; |
254 | int totalY = end_y - start_y; | 254 | int totalY = end_y - start_y; |
255 | int x, y; | 255 | int x, y; |
256 | for (y = 0; y < totalY; y++) | 256 | for (y = 0; y < totalY; y++) |
257 | { | 257 | { |
258 | for (x = 0; x < totalX; x++) | 258 | for (x = 0; x < totalX; x++) |
259 | { | 259 | { |
260 | Land tempLandObject = getLandObject(start_x + x, start_y + y); | 260 | Land tempLandObject = getLandObject(start_x + x, start_y + y); |
261 | if (tempLandObject == null) return false; //No such land object at that point | 261 | if (tempLandObject == null) return false; //No such land object at that point |
262 | if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no | 262 | if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no |
263 | } | 263 | } |
264 | } | 264 | } |
265 | } | 265 | } |
266 | catch (Exception) | 266 | catch (Exception) |
267 | { | 267 | { |
268 | return false; //Exception. For now, lets skip subdivision | 268 | return false; //Exception. For now, lets skip subdivision |
269 | } | 269 | } |
270 | 270 | ||
271 | //If we are still here, then they are subdividing within one piece of land | 271 | //If we are still here, then they are subdividing within one piece of land |
272 | //Check owner | 272 | //Check owner |
273 | if (startLandObject.landData.ownerID != attempting_user_id) | 273 | if (startLandObject.landData.ownerID != attempting_user_id) |
274 | { | 274 | { |
275 | return false; //They cant do this! | 275 | return false; //They cant do this! |
276 | } | 276 | } |
277 | 277 | ||
278 | //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) | 278 | //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) |
279 | Land newLand = startLandObject.Copy(); | 279 | Land newLand = startLandObject.Copy(); |
280 | newLand.landData.landName = "Subdivision of " + newLand.landData.landName; | 280 | newLand.landData.landName = "Subdivision of " + newLand.landData.landName; |
281 | newLand.landData.globalID = LLUUID.Random(); | 281 | newLand.landData.globalID = LLUUID.Random(); |
282 | 282 | ||
283 | newLand.setLandBitmap(Land.getSquareLandBitmap(start_x, start_y, end_x, end_y)); | 283 | newLand.setLandBitmap(Land.getSquareLandBitmap(start_x, start_y, end_x, end_y)); |
284 | 284 | ||
285 | //Now, lets set the subdivision area of the original to false | 285 | //Now, lets set the subdivision area of the original to false |
286 | int startLandObjectIndex = startLandObject.landData.localID; | 286 | int startLandObjectIndex = startLandObject.landData.localID; |
287 | landList[startLandObjectIndex].setLandBitmap(Land.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); | 287 | landList[startLandObjectIndex].setLandBitmap(Land.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); |
288 | landList[startLandObjectIndex].forceUpdateLandInfo(); | 288 | landList[startLandObjectIndex].forceUpdateLandInfo(); |
289 | 289 | ||
290 | 290 | ||
291 | this.setPrimsTainted(); | 291 | this.setPrimsTainted(); |
292 | 292 | ||
293 | //Now add the new land object | 293 | //Now add the new land object |
294 | Land result = addLandObject(newLand); | 294 | Land result = addLandObject(newLand); |
295 | result.sendLandUpdateToAvatarsOverMe(); | 295 | result.sendLandUpdateToAvatarsOverMe(); |
296 | 296 | ||
297 | 297 | ||
298 | 298 | ||
299 | 299 | ||
300 | return true; | 300 | return true; |
301 | } | 301 | } |
302 | /// <summary> | 302 | /// <summary> |
303 | /// Join 2 land objects together | 303 | /// Join 2 land objects together |
304 | /// </summary> | 304 | /// </summary> |
305 | /// <param name="start_x">x value in first piece of land</param> | 305 | /// <param name="start_x">x value in first piece of land</param> |
306 | /// <param name="start_y">y value in first piece of land</param> | 306 | /// <param name="start_y">y value in first piece of land</param> |
307 | /// <param name="end_x">x value in second peice of land</param> | 307 | /// <param name="end_x">x value in second peice of land</param> |
308 | /// <param name="end_y">y value in second peice of land</param> | 308 | /// <param name="end_y">y value in second peice of land</param> |
309 | /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> | 309 | /// <param name="attempting_user_id">LLUUID of the avatar trying to join the land objects</param> |
310 | /// <returns>Returns true if successful</returns> | 310 | /// <returns>Returns true if successful</returns> |
311 | private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 311 | private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
312 | { | 312 | { |
313 | end_x -= 4; | 313 | end_x -= 4; |
314 | end_y -= 4; | 314 | end_y -= 4; |
315 | 315 | ||
316 | List<Land> selectedLandObjects = new List<Land>(); | 316 | List<Land> selectedLandObjects = new List<Land>(); |
317 | int stepXSelected = 0; | 317 | int stepXSelected = 0; |
318 | int stepYSelected = 0; | 318 | int stepYSelected = 0; |
319 | for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) | 319 | for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) |
320 | { | 320 | { |
321 | for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) | 321 | for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) |
322 | { | 322 | { |
323 | Land p = getLandObject(stepXSelected,stepYSelected); | 323 | Land p = getLandObject(stepXSelected,stepYSelected); |
324 | if (!selectedLandObjects.Contains(p)) | 324 | if (!selectedLandObjects.Contains(p)) |
325 | { | 325 | { |
326 | selectedLandObjects.Add(p); | 326 | selectedLandObjects.Add(p); |
327 | } | 327 | } |
328 | } | 328 | } |
329 | } | 329 | } |
330 | Land masterLandObject = selectedLandObjects[0]; | 330 | Land masterLandObject = selectedLandObjects[0]; |
331 | selectedLandObjects.RemoveAt(0); | 331 | selectedLandObjects.RemoveAt(0); |
332 | 332 | ||
333 | 333 | ||
334 | if (selectedLandObjects.Count < 1) | 334 | if (selectedLandObjects.Count < 1) |
335 | { | 335 | { |
336 | return false; //Only one piece of land selected | 336 | return false; //Only one piece of land selected |
337 | } | 337 | } |
338 | if (masterLandObject.landData.ownerID != attempting_user_id) | 338 | if (masterLandObject.landData.ownerID != attempting_user_id) |
339 | { | 339 | { |
340 | return false; //Not the same owner | 340 | return false; //Not the same owner |
341 | } | 341 | } |
342 | foreach (Land p in selectedLandObjects) | 342 | foreach (Land p in selectedLandObjects) |
343 | { | 343 | { |
344 | if (p.landData.ownerID != masterLandObject.landData.ownerID) | 344 | if (p.landData.ownerID != masterLandObject.landData.ownerID) |
345 | { | 345 | { |
346 | return false; //Over multiple users. TODO: make this just ignore this piece of land? | 346 | return false; //Over multiple users. TODO: make this just ignore this piece of land? |
347 | } | 347 | } |
348 | } | 348 | } |
349 | foreach (Land slaveLandObject in selectedLandObjects) | 349 | foreach (Land slaveLandObject in selectedLandObjects) |
350 | { | 350 | { |
351 | landList[masterLandObject.landData.localID].setLandBitmap(Land.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); | 351 | landList[masterLandObject.landData.localID].setLandBitmap(Land.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); |
352 | performFinalLandJoin(masterLandObject, slaveLandObject); | 352 | performFinalLandJoin(masterLandObject, slaveLandObject); |
353 | } | 353 | } |
354 | 354 | ||
355 | 355 | ||
356 | this.setPrimsTainted(); | 356 | this.setPrimsTainted(); |
357 | 357 | ||
358 | masterLandObject.sendLandUpdateToAvatarsOverMe(); | 358 | masterLandObject.sendLandUpdateToAvatarsOverMe(); |
359 | 359 | ||
360 | return true; | 360 | return true; |
361 | 361 | ||
362 | 362 | ||
363 | 363 | ||
364 | } | 364 | } |
365 | #endregion | 365 | #endregion |
366 | 366 | ||
367 | #region Parcel Updating | 367 | #region Parcel Updating |
368 | /// <summary> | 368 | /// <summary> |
369 | /// Where we send the ParcelOverlay packet to the client | 369 | /// Where we send the ParcelOverlay packet to the client |
370 | /// </summary> | 370 | /// </summary> |
371 | /// <param name="remote_client">The object representing the client</param> | 371 | /// <param name="remote_client">The object representing the client</param> |
372 | public void sendParcelOverlay(IClientAPI remote_client) | 372 | public void sendParcelOverlay(IClientAPI remote_client) |
373 | { | 373 | { |
374 | const int LAND_BLOCKS_PER_PACKET = 1024; | 374 | const int LAND_BLOCKS_PER_PACKET = 1024; |
375 | int x, y = 0; | 375 | int x, y = 0; |
376 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 376 | byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
377 | int byteArrayCount = 0; | 377 | int byteArrayCount = 0; |
378 | int sequenceID = 0; | 378 | int sequenceID = 0; |
379 | ParcelOverlayPacket packet; | 379 | ParcelOverlayPacket packet; |
380 | 380 | ||
381 | for (y = 0; y < 64; y++) | 381 | for (y = 0; y < 64; y++) |
382 | { | 382 | { |
383 | for (x = 0; x < 64; x++) | 383 | for (x = 0; x < 64; x++) |
384 | { | 384 | { |
385 | byte tempByte = (byte)0; //This represents the byte for the current 4x4 | 385 | byte tempByte = (byte)0; //This represents the byte for the current 4x4 |
386 | Land currentParcelBlock = getLandObject(x * 4, y * 4); | 386 | Land currentParcelBlock = getLandObject(x * 4, y * 4); |
387 | 387 | ||
388 | if (currentParcelBlock.landData.ownerID == remote_client.AgentId) | 388 | if (currentParcelBlock.landData.ownerID == remote_client.AgentId) |
389 | { | 389 | { |
390 | //Owner Flag | 390 | //Owner Flag |
391 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); | 391 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); |
392 | } | 392 | } |
393 | else if (currentParcelBlock.landData.salePrice > 0 && (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) | 393 | else if (currentParcelBlock.landData.salePrice > 0 && (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) |
394 | { | 394 | { |
395 | //Sale Flag | 395 | //Sale Flag |
396 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); | 396 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); |
397 | } | 397 | } |
398 | else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) | 398 | else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) |
399 | { | 399 | { |
400 | //Public Flag | 400 | //Public Flag |
401 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); | 401 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); |
402 | } | 402 | } |
403 | else | 403 | else |
404 | { | 404 | { |
405 | //Other Flag | 405 | //Other Flag |
406 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); | 406 | tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); |
407 | } | 407 | } |
408 | 408 | ||
409 | 409 | ||
410 | //Now for border control | 410 | //Now for border control |
411 | if (x == 0) | 411 | if (x == 0) |
412 | { | 412 | { |
413 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); | 413 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); |
414 | } | 414 | } |
415 | else if (getLandObject((x - 1) * 4, y * 4) != currentParcelBlock) | 415 | else if (getLandObject((x - 1) * 4, y * 4) != currentParcelBlock) |
416 | { | 416 | { |
417 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); | 417 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); |
418 | } | 418 | } |
419 | 419 | ||
420 | if (y == 0) | 420 | if (y == 0) |
421 | { | 421 | { |
422 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); | 422 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); |
423 | } | 423 | } |
424 | else if (getLandObject(x * 4, (y - 1) * 4) != currentParcelBlock) | 424 | else if (getLandObject(x * 4, (y - 1) * 4) != currentParcelBlock) |
425 | { | 425 | { |
426 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); | 426 | tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); |
427 | } | 427 | } |
428 | 428 | ||
429 | byteArray[byteArrayCount] = tempByte; | 429 | byteArray[byteArrayCount] = tempByte; |
430 | byteArrayCount++; | 430 | byteArrayCount++; |
431 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 431 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
432 | { | 432 | { |
433 | byteArrayCount = 0; | 433 | byteArrayCount = 0; |
434 | packet = new ParcelOverlayPacket(); | 434 | packet = new ParcelOverlayPacket(); |
435 | packet.ParcelData.Data = byteArray; | 435 | packet.ParcelData.Data = byteArray; |
436 | packet.ParcelData.SequenceID = sequenceID; | 436 | packet.ParcelData.SequenceID = sequenceID; |
437 | remote_client.OutPacket((Packet)packet); | 437 | remote_client.OutPacket((Packet)packet); |
438 | sequenceID++; | 438 | sequenceID++; |
439 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; | 439 | byteArray = new byte[LAND_BLOCKS_PER_PACKET]; |
440 | } | 440 | } |
441 | } | 441 | } |
442 | } | 442 | } |
443 | 443 | ||
444 | 444 | ||
445 | } | 445 | } |
446 | 446 | ||
447 | public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client) | 447 | public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client) |
448 | { | 448 | { |
449 | //Get the land objects within the bounds | 449 | //Get the land objects within the bounds |
450 | List<Land> temp = new List<Land>(); | 450 | List<Land> temp = new List<Land>(); |
451 | int x, y, i; | 451 | int x, y, i; |
452 | int inc_x = end_x - start_x; | 452 | int inc_x = end_x - start_x; |
453 | int inc_y = end_y - start_y; | 453 | int inc_y = end_y - start_y; |
454 | for (x = 0; x < inc_x; x++) | 454 | for (x = 0; x < inc_x; x++) |
455 | { | 455 | { |
456 | for (y = 0; y < inc_y; y++) | 456 | for (y = 0; y < inc_y; y++) |
457 | { | 457 | { |
458 | Land currentParcel = getLandObject(start_x + x, start_y + y); | 458 | Land currentParcel = getLandObject(start_x + x, start_y + y); |
459 | if (!temp.Contains(currentParcel)) | 459 | if (!temp.Contains(currentParcel)) |
460 | { | 460 | { |
461 | currentParcel.forceUpdateLandInfo(); | 461 | currentParcel.forceUpdateLandInfo(); |
462 | temp.Add(currentParcel); | 462 | temp.Add(currentParcel); |
463 | } | 463 | } |
464 | } | 464 | } |
465 | } | 465 | } |
466 | 466 | ||
467 | int requestResult = LAND_RESULT_SINGLE; | 467 | int requestResult = LAND_RESULT_SINGLE; |
468 | if (temp.Count > 1) | 468 | if (temp.Count > 1) |
469 | { | 469 | { |
470 | requestResult = LAND_RESULT_MULTIPLE; | 470 | requestResult = LAND_RESULT_MULTIPLE; |
471 | } | 471 | } |
472 | 472 | ||
473 | for (i = 0; i < temp.Count; i++) | 473 | for (i = 0; i < temp.Count; i++) |
474 | { | 474 | { |
475 | temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); | 475 | temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); |
476 | } | 476 | } |
477 | 477 | ||
478 | 478 | ||
479 | sendParcelOverlay(remote_client); | 479 | sendParcelOverlay(remote_client); |
480 | } | 480 | } |
481 | 481 | ||
482 | public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) | 482 | public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) |
483 | { | 483 | { |
484 | if (landList.ContainsKey(packet.ParcelData.LocalID)) | 484 | if (landList.ContainsKey(packet.ParcelData.LocalID)) |
485 | { | 485 | { |
486 | landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); | 486 | landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); |
487 | } | 487 | } |
488 | } | 488 | } |
489 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) | 489 | public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) |
490 | { | 490 | { |
491 | subdivide(west, south, east, north, remote_client.AgentId); | 491 | subdivide(west, south, east, north, remote_client.AgentId); |
492 | } | 492 | } |
493 | public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) | 493 | public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) |
494 | { | 494 | { |
495 | join(west, south, east, north, remote_client.AgentId); | 495 | join(west, south, east, north, remote_client.AgentId); |
496 | 496 | ||
497 | } | 497 | } |
498 | 498 | ||
499 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) | 499 | public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) |
500 | { | 500 | { |
501 | landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); | 501 | landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); |
502 | } | 502 | } |
503 | 503 | ||
504 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) | 504 | public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) |
505 | { | 505 | { |
506 | landList[local_id].sendLandObjectOwners(remote_client); | 506 | landList[local_id].sendLandObjectOwners(remote_client); |
507 | } | 507 | } |
508 | #endregion | 508 | #endregion |
509 | 509 | ||
510 | /// <summary> | 510 | /// <summary> |
511 | /// Resets the sim to the default land object (full sim piece of land owned by the default user) | 511 | /// Resets the sim to the default land object (full sim piece of land owned by the default user) |
512 | /// </summary> | 512 | /// </summary> |
513 | public void resetSimLandObjects() | 513 | public void resetSimLandObjects() |
514 | { | 514 | { |
515 | //Remove all the land objects in the sim and add a blank, full sim land object set to public | 515 | //Remove all the land objects in the sim and add a blank, full sim land object set to public |
516 | landList.Clear(); | 516 | landList.Clear(); |
517 | lastLandLocalID = START_LAND_LOCAL_ID - 1; | 517 | lastLandLocalID = START_LAND_LOCAL_ID - 1; |
518 | landIDList.Initialize(); | 518 | landIDList.Initialize(); |
519 | 519 | ||
520 | Land fullSimParcel = new Land(LLUUID.Zero, false, m_scene); | 520 | Land fullSimParcel = new Land(LLUUID.Zero, false, m_scene); |
521 | 521 | ||
522 | fullSimParcel.setLandBitmap(Land.getSquareLandBitmap(0, 0, 256, 256)); | 522 | fullSimParcel.setLandBitmap(Land.getSquareLandBitmap(0, 0, 256, 256)); |
523 | fullSimParcel.landData.ownerID = m_regInfo.MasterAvatarAssignedUUID; | 523 | fullSimParcel.landData.ownerID = m_regInfo.MasterAvatarAssignedUUID; |
524 | 524 | ||
525 | addLandObject(fullSimParcel); | 525 | addLandObject(fullSimParcel); |
526 | 526 | ||
527 | } | 527 | } |
528 | 528 | ||
529 | 529 | ||
530 | public void handleSignificantClientMovement(IClientAPI remote_client) | 530 | public void handleSignificantClientMovement(IClientAPI remote_client) |
531 | { | 531 | { |
532 | ScenePresence clientAvatar = m_scene.RequestAvatar(remote_client.AgentId); | 532 | ScenePresence clientAvatar = m_scene.RequestAvatar(remote_client.AgentId); |
533 | if (clientAvatar != null) | 533 | if (clientAvatar != null) |
534 | { | 534 | { |
535 | Land over = getLandObject(clientAvatar.Pos.X,clientAvatar.Pos.Y); | 535 | Land over = getLandObject(clientAvatar.Pos.X,clientAvatar.Pos.Y); |
536 | if (over != null) | 536 | if (over != null) |
537 | { | 537 | { |
538 | over.sendLandProperties(0, false, 0, remote_client); | 538 | over.sendLandProperties(0, false, 0, remote_client); |
539 | } | 539 | } |
540 | } | 540 | } |
541 | } | 541 | } |
542 | 542 | ||
543 | public void resetAllLandPrimCounts() | 543 | public void resetAllLandPrimCounts() |
544 | { | 544 | { |
545 | foreach (Land p in landList.Values) | 545 | foreach (Land p in landList.Values) |
546 | { | 546 | { |
547 | p.resetLandPrimCounts(); | 547 | p.resetLandPrimCounts(); |
548 | } | 548 | } |
549 | } | 549 | } |
550 | public void setPrimsTainted() | 550 | public void setPrimsTainted() |
551 | { | 551 | { |
552 | this.landPrimCountTainted = true; | 552 | this.landPrimCountTainted = true; |
553 | } | 553 | } |
554 | 554 | ||
555 | public void addPrimToLandPrimCounts(SceneObject obj) | 555 | public void addPrimToLandPrimCounts(SceneObject obj) |
556 | { | 556 | { |
557 | LLVector3 position = obj.Pos; | 557 | LLVector3 position = obj.Pos; |
558 | Land landUnderPrim = getLandObject(position.X, position.Y); | 558 | Land landUnderPrim = getLandObject(position.X, position.Y); |
559 | if (landUnderPrim != null) | 559 | if (landUnderPrim != null) |
560 | { | 560 | { |
561 | landUnderPrim.addPrimToCount(obj); | 561 | landUnderPrim.addPrimToCount(obj); |
562 | } | 562 | } |
563 | } | 563 | } |
564 | 564 | ||
565 | public void removePrimFromLandPrimCounts(SceneObject obj) | 565 | public void removePrimFromLandPrimCounts(SceneObject obj) |
566 | { | 566 | { |
567 | foreach (Land p in landList.Values) | 567 | foreach (Land p in landList.Values) |
568 | { | 568 | { |
569 | p.removePrimFromCount(obj); | 569 | p.removePrimFromCount(obj); |
570 | } | 570 | } |
571 | } | 571 | } |
572 | 572 | ||
573 | public void finalizeLandPrimCountUpdate() | 573 | public void finalizeLandPrimCountUpdate() |
574 | { | 574 | { |
575 | //Get Simwide prim count for owner | 575 | //Get Simwide prim count for owner |
576 | Dictionary<LLUUID, List<Land>> landOwnersAndParcels = new Dictionary<LLUUID,List<Land>>(); | 576 | Dictionary<LLUUID, List<Land>> landOwnersAndParcels = new Dictionary<LLUUID,List<Land>>(); |
577 | foreach (Land p in landList.Values) | 577 | foreach (Land p in landList.Values) |
578 | { | 578 | { |
579 | if(!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) | 579 | if(!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) |
580 | { | 580 | { |
581 | List<Land> tempList = new List<Land>(); | 581 | List<Land> tempList = new List<Land>(); |
582 | tempList.Add(p); | 582 | tempList.Add(p); |
583 | landOwnersAndParcels.Add(p.landData.ownerID,tempList); | 583 | landOwnersAndParcels.Add(p.landData.ownerID,tempList); |
584 | } | 584 | } |
585 | else | 585 | else |
586 | { | 586 | { |
587 | landOwnersAndParcels[p.landData.ownerID].Add(p); | 587 | landOwnersAndParcels[p.landData.ownerID].Add(p); |
588 | } | 588 | } |
589 | } | 589 | } |
590 | 590 | ||
591 | foreach (LLUUID owner in landOwnersAndParcels.Keys) | 591 | foreach (LLUUID owner in landOwnersAndParcels.Keys) |
592 | { | 592 | { |
593 | int simArea = 0; | 593 | int simArea = 0; |
594 | int simPrims = 0; | 594 | int simPrims = 0; |
595 | foreach (Land p in landOwnersAndParcels[owner]) | 595 | foreach (Land p in landOwnersAndParcels[owner]) |
596 | { | 596 | { |
597 | simArea += p.landData.area; | 597 | simArea += p.landData.area; |
598 | simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + p.landData.selectedPrims; | 598 | simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + p.landData.selectedPrims; |
599 | } | 599 | } |
600 | 600 | ||
601 | foreach (Land p in landOwnersAndParcels[owner]) | 601 | foreach (Land p in landOwnersAndParcels[owner]) |
602 | { | 602 | { |
603 | p.landData.simwideArea = simArea; | 603 | p.landData.simwideArea = simArea; |
604 | p.landData.simwidePrims = simPrims; | 604 | p.landData.simwidePrims = simPrims; |
605 | } | 605 | } |
606 | } | 606 | } |
607 | 607 | ||
608 | } | 608 | } |
609 | #endregion | 609 | #endregion |
610 | } | 610 | } |
611 | #endregion | 611 | #endregion |
612 | 612 | ||
613 | 613 | ||
614 | 614 | ||
615 | 615 | ||
616 | 616 | ||
617 | } | 617 | } |