diff options
author | mingchen | 2007-06-04 14:09:19 +0000 |
---|---|---|
committer | mingchen | 2007-06-04 14:09:19 +0000 |
commit | 17421593528f4126256dea6d0c844da9c218fdb7 (patch) | |
tree | 69025fb439a08c24787a226b708f7b271610c548 /OpenSim/OpenSim.RegionServer/world/ParcelManager.cs | |
parent | Small bugfix. (diff) | |
download | opensim-SC_OLD-17421593528f4126256dea6d0c844da9c218fdb7.zip opensim-SC_OLD-17421593528f4126256dea6d0c844da9c218fdb7.tar.gz opensim-SC_OLD-17421593528f4126256dea6d0c844da9c218fdb7.tar.bz2 opensim-SC_OLD-17421593528f4126256dea6d0c844da9c218fdb7.tar.xz |
Parcel Manager Changes:
*Added Parcel Backup Support for DB4. Other storages currently do not save
*Added parcelIDList in ParcelManager to speed up parcel fetching at position
*Added ParcelData.cs and ParcelData class for better storage support
*Documentation for parcel added
*2 Parcel Related bug fixes
Diffstat (limited to 'OpenSim/OpenSim.RegionServer/world/ParcelManager.cs')
-rw-r--r-- | OpenSim/OpenSim.RegionServer/world/ParcelManager.cs | 499 |
1 files changed, 270 insertions, 229 deletions
diff --git a/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs index 7cc39ff..53b14f3 100644 --- a/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs +++ b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs | |||
@@ -3,168 +3,54 @@ using System.Collections.Generic; | |||
3 | using System.Text; | 3 | using System.Text; |
4 | using libsecondlife; | 4 | using libsecondlife; |
5 | using libsecondlife.Packets; | 5 | using libsecondlife.Packets; |
6 | using OpenSim.world; | ||
7 | using OpenSim.Framework.Interfaces; | ||
8 | using OpenSim.Framework.Types; | ||
6 | 9 | ||
7 | namespace OpenSim.world | 10 | namespace OpenSim.RegionServer.world |
8 | { | 11 | { |
9 | public delegate void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client); | 12 | public delegate void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, ClientView remote_client); |
10 | |||
11 | #region Enums | ||
12 | public enum ParcelFlags : uint | ||
13 | { | ||
14 | /// <summary>No flags set</summary> | ||
15 | None = 0, | ||
16 | /// <summary>Allow avatars to fly (a client-side only restriction)</summary> | ||
17 | AllowFly = 1 << 0, | ||
18 | /// <summary>Allow foreign scripts to run</summary> | ||
19 | AllowOtherScripts = 1 << 1, | ||
20 | /// <summary>This parcel is for sale</summary> | ||
21 | ForSale = 1 << 2, | ||
22 | /// <summary>Allow avatars to create a landmark on this parcel</summary> | ||
23 | AllowLandmark = 1 << 3, | ||
24 | /// <summary>Allows all avatars to edit the terrain on this parcel</summary> | ||
25 | AllowTerraform = 1 << 4, | ||
26 | /// <summary>Avatars have health and can take damage on this parcel. | ||
27 | /// If set, avatars can be killed and sent home here</summary> | ||
28 | AllowDamage = 1 << 5, | ||
29 | /// <summary>Foreign avatars can create objects here</summary> | ||
30 | CreateObjects = 1 << 6, | ||
31 | /// <summary>All objects on this parcel can be purchased</summary> | ||
32 | ForSaleObjects = 1 << 7, | ||
33 | /// <summary>Access is restricted to a group</summary> | ||
34 | UseAccessGroup = 1 << 8, | ||
35 | /// <summary>Access is restricted to a whitelist</summary> | ||
36 | UseAccessList = 1 << 9, | ||
37 | /// <summary>Ban blacklist is enabled</summary> | ||
38 | UseBanList = 1 << 10, | ||
39 | /// <summary>Unknown</summary> | ||
40 | UsePassList = 1 << 11, | ||
41 | /// <summary>List this parcel in the search directory</summary> | ||
42 | ShowDirectory = 1 << 12, | ||
43 | /// <summary>Unknown</summary> | ||
44 | AllowDeedToGroup = 1 << 13, | ||
45 | /// <summary>Unknown</summary> | ||
46 | ContributeWithDeed = 1 << 14, | ||
47 | /// <summary>Restrict sounds originating on this parcel to the | ||
48 | /// parcel boundaries</summary> | ||
49 | SoundLocal = 1 << 15, | ||
50 | /// <summary>Objects on this parcel are sold when the land is | ||
51 | /// purchsaed</summary> | ||
52 | SellParcelObjects = 1 << 16, | ||
53 | /// <summary>Allow this parcel to be published on the web</summary> | ||
54 | AllowPublish = 1 << 17, | ||
55 | /// <summary>The information for this parcel is mature content</summary> | ||
56 | MaturePublish = 1 << 18, | ||
57 | /// <summary>The media URL is an HTML page</summary> | ||
58 | UrlWebPage = 1 << 19, | ||
59 | /// <summary>The media URL is a raw HTML string</summary> | ||
60 | UrlRawHtml = 1 << 20, | ||
61 | /// <summary>Restrict foreign object pushes</summary> | ||
62 | RestrictPushObject = 1 << 21, | ||
63 | /// <summary>Ban all non identified/transacted avatars</summary> | ||
64 | DenyAnonymous = 1 << 22, | ||
65 | /// <summary>Ban all identified avatars</summary> | ||
66 | DenyIdentified = 1 << 23, | ||
67 | /// <summary>Ban all transacted avatars</summary> | ||
68 | DenyTransacted = 1 << 24, | ||
69 | /// <summary>Allow group-owned scripts to run</summary> | ||
70 | AllowGroupScripts = 1 << 25, | ||
71 | /// <summary>Allow object creation by group members or group | ||
72 | /// objects</summary> | ||
73 | CreateGroupObjects = 1 << 26, | ||
74 | /// <summary>Allow all objects to enter this parcel</summary> | ||
75 | AllowAllObjectEntry = 1 << 27, | ||
76 | /// <summary>Only allow group and owner objects to enter this parcel</summary> | ||
77 | AllowGroupObjectEntry = 1 << 28, | ||
78 | } | ||
79 | 13 | ||
14 | |||
15 | #region ParcelManager Class | ||
80 | /// <summary> | 16 | /// <summary> |
81 | /// Parcel ownership status | 17 | /// Handles Parcel objects and operations requiring information from other Parcel objects (divide, join, etc) |
82 | /// </summary> | 18 | /// </summary> |
83 | public enum ParcelStatus : sbyte | 19 | public class ParcelManager : OpenSim.Framework.Interfaces.ILocalStorageParcelReceiver |
84 | { | 20 | { |
85 | /// <summary>Eh?</summary> | ||
86 | None = -1, | ||
87 | /// <summary>Land is owned</summary> | ||
88 | Leased = 0, | ||
89 | /// <summary>Land is for sale</summary> | ||
90 | LeasePending = 1, | ||
91 | /// <summary>Land is public</summary> | ||
92 | Abandoned = 2 | ||
93 | } | ||
94 | 21 | ||
95 | public enum ParcelCategory : sbyte | ||
96 | { | ||
97 | /// <summary>No assigned category</summary> | ||
98 | None = 0, | ||
99 | /// <summary></summary> | ||
100 | Linden, | ||
101 | /// <summary></summary> | ||
102 | Adult, | ||
103 | /// <summary></summary> | ||
104 | Arts, | ||
105 | /// <summary></summary> | ||
106 | Business, | ||
107 | /// <summary></summary> | ||
108 | Educational, | ||
109 | /// <summary></summary> | ||
110 | Gaming, | ||
111 | /// <summary></summary> | ||
112 | Hangout, | ||
113 | /// <summary></summary> | ||
114 | Newcomer, | ||
115 | /// <summary></summary> | ||
116 | Park, | ||
117 | /// <summary></summary> | ||
118 | Residential, | ||
119 | /// <summary></summary> | ||
120 | Shopping, | ||
121 | /// <summary></summary> | ||
122 | Stage, | ||
123 | /// <summary></summary> | ||
124 | Other, | ||
125 | /// <summary>Not an actual category, only used for queries</summary> | ||
126 | Any = -1 | ||
127 | } | ||
128 | |||
129 | #endregion | ||
130 | |||
131 | #region ParcelManager Class | ||
132 | public class ParcelManager | ||
133 | { | ||
134 | |||
135 | #region Constants | 22 | #region Constants |
136 | //Parcel types set with flags in ParcelOverlay. | 23 | //Parcel types set with flags in ParcelOverlay. |
137 | //Only one of these can be used. | 24 | //Only one of these can be used. |
138 | public static byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000 | 25 | public static byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000 |
139 | public static byte PARCEL_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 | 26 | public static byte PARCEL_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 |
140 | public static byte PARCEL_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 | 27 | public static byte PARCEL_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 |
141 | public static byte PARCEL_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 | 28 | public static byte PARCEL_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 |
142 | public static byte PARCEL_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 | 29 | public static byte PARCEL_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 |
143 | public static byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 | 30 | public static byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 |
144 | 31 | ||
145 | 32 | ||
146 | //Flags that when set, a border on the given side will be placed | 33 | //Flags that when set, a border on the given side will be placed |
147 | //NOTE: North and East is assumable by the west and south sides (if parcel to east has a west border, then I have an east border; etc) | 34 | //NOTE: North and East is assumable by the west and south sides (if parcel to east has a west border, then I have an east border; etc) |
148 | //This took forever to figure out -- jeesh. /blame LL for even having to send these | 35 | //This took forever to figure out -- jeesh. /blame LL for even having to send these |
149 | public static byte PARCEL_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 | 36 | public static byte PARCEL_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 |
150 | public static byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 | 37 | public static byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 |
151 | 38 | ||
152 | #endregion | 39 | #endregion |
153 | 40 | ||
154 | #region Member Variables | 41 | #region Member Variables |
155 | private List<Parcel> parcelList; | 42 | public Dictionary<int, Parcel> parcelList = new Dictionary<int, Parcel>(); |
156 | private static World m_world; | 43 | private int lastParcelLocalID = -1; |
44 | private int[,] parcelIDList = new int[64, 64]; | ||
45 | |||
46 | private static World m_world; | ||
157 | #endregion | 47 | #endregion |
158 | 48 | ||
159 | #region Constructors | 49 | #region Constructors |
160 | public ParcelManager(World world) | 50 | public ParcelManager(World world) |
161 | { | 51 | { |
162 | parcelList = new List<Parcel>(); | 52 | |
163 | m_world = world; | 53 | m_world = world; |
164 | |||
165 | //NOTE: This is temporary until I get to storing the parcels out of memory | ||
166 | //This should later only be for new simulators | ||
167 | resetSimParcels(); | ||
168 | Console.WriteLine("Created ParcelManager Object"); | 54 | Console.WriteLine("Created ParcelManager Object"); |
169 | 55 | ||
170 | 56 | ||
@@ -173,38 +59,112 @@ namespace OpenSim.world | |||
173 | 59 | ||
174 | #region Member Functions | 60 | #region Member Functions |
175 | 61 | ||
176 | #region Parcel Add/Remove/Get | 62 | #region Parcel From Storage Functions |
177 | public void addParcel(Parcel new_parcel) | 63 | public void ParcelFromStorage(ParcelData data) |
178 | { | 64 | { |
179 | parcelList.Add(new_parcel); | 65 | Parcel new_parcel = new Parcel(data.ownerID, data.isGroupOwned, m_world); |
66 | new_parcel.parcelData = data; | ||
67 | new_parcel.setParcelBitmapFromByteArray(); | ||
68 | |||
69 | this.addParcel(new_parcel); | ||
180 | } | 70 | } |
181 | public void removeParcel(Parcel old_parcel) | 71 | |
72 | public void NoParcelDataFromStorage() | ||
182 | { | 73 | { |
183 | parcelList.Remove(old_parcel); | 74 | this.resetSimParcels(); |
184 | } | 75 | } |
185 | public Parcel getParcel(int x, int y) | 76 | #endregion |
77 | |||
78 | #region Parcel Add/Remove/Get/Create | ||
79 | /// <summary> | ||
80 | /// Creates a basic Parcel object without an owner (a zeroed key) | ||
81 | /// </summary> | ||
82 | /// <returns></returns> | ||
83 | public Parcel createBaseParcel() | ||
84 | { | ||
85 | return new Parcel(new LLUUID(), false, m_world); | ||
86 | } | ||
87 | |||
88 | /// <summary> | ||
89 | /// Adds a parcel to the stored list and adds them to the parcelIDList to what they own | ||
90 | /// </summary> | ||
91 | /// <param name="new_parcel">The parcel being added</param> | ||
92 | public void addParcel(Parcel new_parcel) | ||
93 | { | ||
94 | lastParcelLocalID++; | ||
95 | new_parcel.parcelData.localID = lastParcelLocalID; | ||
96 | parcelList.Add(lastParcelLocalID, new_parcel); | ||
97 | |||
98 | |||
99 | bool[,] parcelBitmap = new_parcel.getParcelBitmap(); | ||
100 | int x, y; | ||
101 | for (x = 0; x < 64; x++) | ||
102 | { | ||
103 | for (y = 0; y < 64; y++) | ||
104 | { | ||
105 | if (parcelBitmap[x, y]) | ||
106 | { | ||
107 | parcelIDList[x, y] = lastParcelLocalID; | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | /// <summary> | ||
113 | /// Removes a parcel from the list. Will not remove if local_id is still owning an area in parcelIDList | ||
114 | /// </summary> | ||
115 | /// <param name="local_id">Parcel.localID of the parcel to remove.</param> | ||
116 | public void removeParcel(int local_id) | ||
186 | { | 117 | { |
187 | int searchParcel; | 118 | int x, y; |
188 | for(searchParcel = 0; searchParcel < this.parcelList.Count; searchParcel++) | 119 | for (x = 0; x < 64; x++) |
189 | { | 120 | { |
190 | if(parcelList[searchParcel].containsPoint(x,y)) | 121 | for (y = 0; y < 64; y++) |
191 | { | 122 | { |
192 | return this.parcelList[searchParcel]; | 123 | if (parcelIDList[x, y] == local_id) |
124 | { | ||
125 | throw new Exception("Could not remove parcel. Still being used at " + x + ", " + y); | ||
126 | } | ||
193 | } | 127 | } |
194 | } | 128 | } |
195 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | 129 | parcelList.Remove(local_id); |
130 | } | ||
131 | /// <summary> | ||
132 | /// Get the parcel at the specified point | ||
133 | /// </summary> | ||
134 | /// <param name="x">Value between 0 - 256 on the x axis of the point</param> | ||
135 | /// <param name="y">Value between 0 - 256 on the y axis of the point</param> | ||
136 | /// <returns>Parcel at the point supplied</returns> | ||
137 | public Parcel getParcel(int x, int y) | ||
138 | { | ||
139 | if (x > 256 || y > 256 || x < 0 || y < 0) | ||
140 | { | ||
141 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | return parcelList[parcelIDList[x / 4, y / 4]]; | ||
146 | } | ||
196 | 147 | ||
197 | } | 148 | } |
198 | #endregion | 149 | #endregion |
199 | 150 | ||
200 | #region Parcel Modification | 151 | #region Parcel Modification |
152 | /// <summary> | ||
153 | /// Subdivides a parcel | ||
154 | /// </summary> | ||
155 | /// <param name="start_x">West Point</param> | ||
156 | /// <param name="start_y">South Point</param> | ||
157 | /// <param name="end_x">East Point</param> | ||
158 | /// <param name="end_y">North Point</param> | ||
159 | /// <param name="attempting_user_id">LLUUID of user who is trying to subdivide</param> | ||
160 | /// <returns>Returns true if successful</returns> | ||
201 | public bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 161 | public bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
202 | { | 162 | { |
203 | //First, lets loop through the points and make sure they are all in the same parcel | 163 | //First, lets loop through the points and make sure they are all in the same parcel |
204 | //Get the parcel at start | 164 | //Get the parcel at start |
205 | Parcel startParcel = getParcel(start_x, start_y); | 165 | Parcel startParcel = getParcel(start_x, start_y); |
206 | if(startParcel == null) return false; //No such parcel at the beginning | 166 | if (startParcel == null) return false; //No such parcel at the beginning |
207 | 167 | ||
208 | //Loop through the points | 168 | //Loop through the points |
209 | try | 169 | try |
210 | { | 170 | { |
@@ -228,7 +188,7 @@ namespace OpenSim.world | |||
228 | 188 | ||
229 | //If we are still here, then they are subdividing within one parcel | 189 | //If we are still here, then they are subdividing within one parcel |
230 | //Check owner | 190 | //Check owner |
231 | if (startParcel.ownerID != attempting_user_id) | 191 | if (startParcel.parcelData.ownerID != attempting_user_id) |
232 | { | 192 | { |
233 | return false; //They cant do this! | 193 | return false; //They cant do this! |
234 | } | 194 | } |
@@ -236,17 +196,25 @@ namespace OpenSim.world | |||
236 | //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info) | 196 | //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info) |
237 | Parcel newParcel = startParcel; | 197 | Parcel newParcel = startParcel; |
238 | newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y)); | 198 | newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y)); |
239 | 199 | ||
240 | //Now, lets set the subdivision area of the original to false | 200 | //Now, lets set the subdivision area of the original to false |
241 | int startParcelIndex = parcelList.IndexOf(startParcel); | 201 | int startParcelIndex = startParcel.parcelData.localID; |
242 | parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(parcelList[startParcelIndex].getParcelBitmap(),start_x,start_y,end_x, end_y,false)); | 202 | parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(parcelList[startParcelIndex].getParcelBitmap(), start_x, start_y, end_x, end_y, false)); |
243 | 203 | ||
244 | //Now add the new parcel | 204 | //Now add the new parcel |
245 | addParcel(newParcel); | 205 | addParcel(newParcel); |
246 | 206 | ||
247 | return true; | 207 | return true; |
248 | } | 208 | } |
249 | 209 | /// <summary> | |
210 | /// Join 2 parcels together | ||
211 | /// </summary> | ||
212 | /// <param name="start_x">x value in first parcel</param> | ||
213 | /// <param name="start_y">y value in first parcel</param> | ||
214 | /// <param name="end_x">x value in second parcel</param> | ||
215 | /// <param name="end_y">y value in second parcel</param> | ||
216 | /// <param name="attempting_user_id">LLUUID of the avatar trying to join the parcels</param> | ||
217 | /// <returns>Returns true if successful</returns> | ||
250 | public bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | 218 | public bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) |
251 | { | 219 | { |
252 | //NOTE: The following only connects the parcels in each corner and not all the parcels that are within the selection box! | 220 | //NOTE: The following only connects the parcels in each corner and not all the parcels that are within the selection box! |
@@ -262,11 +230,11 @@ namespace OpenSim.world | |||
262 | return false; //Error occured when trying to get the start and end parcels | 230 | return false; //Error occured when trying to get the start and end parcels |
263 | } | 231 | } |
264 | //Check the parcel owners: | 232 | //Check the parcel owners: |
265 | if (startParcel.ownerID != endParcel.ownerID) | 233 | if (startParcel.parcelData.ownerID != endParcel.parcelData.ownerID) |
266 | { | 234 | { |
267 | return false; | 235 | return false; |
268 | } | 236 | } |
269 | if (startParcel.ownerID != attempting_user_id) | 237 | if (startParcel.parcelData.ownerID != attempting_user_id) |
270 | { | 238 | { |
271 | //TODO: Group editing stuff. Avatar owner support for now | 239 | //TODO: Group editing stuff. Avatar owner support for now |
272 | return false; | 240 | return false; |
@@ -274,10 +242,10 @@ namespace OpenSim.world | |||
274 | 242 | ||
275 | //Same owners! Lets join them | 243 | //Same owners! Lets join them |
276 | //Merge them to startParcel | 244 | //Merge them to startParcel |
277 | parcelList[parcelList.IndexOf(startParcel)].setParcelBitmap(Parcel.mergeParcelBitmaps(startParcel.getParcelBitmap(),endParcel.getParcelBitmap())); | 245 | parcelList[startParcel.parcelData.localID].setParcelBitmap(Parcel.mergeParcelBitmaps(startParcel.getParcelBitmap(), endParcel.getParcelBitmap())); |
278 | 246 | ||
279 | //Remove the old parcel | 247 | //Remove the old parcel |
280 | parcelList.Remove(endParcel); | 248 | parcelList.Remove(endParcel.parcelData.localID); |
281 | 249 | ||
282 | return true; | 250 | return true; |
283 | 251 | ||
@@ -307,17 +275,17 @@ namespace OpenSim.world | |||
307 | byte tempByte = (byte)0; //This represents the byte for the current 4x4 | 275 | byte tempByte = (byte)0; //This represents the byte for the current 4x4 |
308 | Parcel currentParcelBlock = getParcel(x * 4, y * 4); | 276 | Parcel currentParcelBlock = getParcel(x * 4, y * 4); |
309 | 277 | ||
310 | if (currentParcelBlock.ownerID == remote_client.AgentID) | 278 | if (currentParcelBlock.parcelData.ownerID == remote_client.AgentID) |
311 | { | 279 | { |
312 | //Owner Flag | 280 | //Owner Flag |
313 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER); | 281 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER); |
314 | } | 282 | } |
315 | else if (currentParcelBlock.salePrice > 0 && (currentParcelBlock.authBuyerID == LLUUID.Zero || currentParcelBlock.authBuyerID == remote_client.AgentID)) | 283 | else if (currentParcelBlock.parcelData.salePrice > 0 && (currentParcelBlock.parcelData.authBuyerID == LLUUID.Zero || currentParcelBlock.parcelData.authBuyerID == remote_client.AgentID)) |
316 | { | 284 | { |
317 | //Sale Flag | 285 | //Sale Flag |
318 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE); | 286 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE); |
319 | } | 287 | } |
320 | else if (currentParcelBlock.ownerID == LLUUID.Zero) | 288 | else if (currentParcelBlock.parcelData.ownerID == LLUUID.Zero) |
321 | { | 289 | { |
322 | //Public Flag | 290 | //Public Flag |
323 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC); | 291 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC); |
@@ -369,57 +337,45 @@ namespace OpenSim.world | |||
369 | remote_client.OutPacket((Packet)packet); | 337 | remote_client.OutPacket((Packet)packet); |
370 | } | 338 | } |
371 | #endregion | 339 | #endregion |
340 | |||
341 | /// <summary> | ||
342 | /// Resets the sim to the default parcel (full sim parcel owned by the default user) | ||
343 | /// </summary> | ||
372 | public void resetSimParcels() | 344 | public void resetSimParcels() |
373 | { | 345 | { |
374 | //Remove all the parcels in the sim and add a blank, full sim parcel set to public | 346 | //Remove all the parcels in the sim and add a blank, full sim parcel set to public |
375 | parcelList.Clear(); | 347 | parcelList.Clear(); |
376 | Parcel fullSimParcel = new Parcel(LLUUID.Zero, false,m_world); | 348 | parcelIDList.Initialize(); |
349 | Parcel fullSimParcel = new Parcel(LLUUID.Zero, false, m_world); | ||
377 | fullSimParcel.setParcelBitmap(Parcel.basicFullRegionParcelBitmap()); | 350 | fullSimParcel.setParcelBitmap(Parcel.basicFullRegionParcelBitmap()); |
378 | fullSimParcel.parcelName = "Your Sim Parcel"; | 351 | fullSimParcel.parcelData.parcelName = "Your Sim Parcel"; |
379 | fullSimParcel.parcelDesc = ""; | 352 | fullSimParcel.parcelData.parcelDesc = ""; |
380 | LLUUID Agent; | ||
381 | int AgentRand = OpenSim.Framework.Utilities.Util.RandomClass.Next(1, 9999); | ||
382 | Agent = new LLUUID("99998888-0100-" + AgentRand.ToString("0000") + "-8ec1-0b1d5cd6aead"); | ||
383 | |||
384 | fullSimParcel.ownerID = Agent; | ||
385 | fullSimParcel.salePrice = 1; | ||
386 | fullSimParcel.parcelFlags = ParcelFlags.ForSale; | ||
387 | 353 | ||
354 | fullSimParcel.parcelData.ownerID = LLUUID.Zero; | ||
355 | fullSimParcel.parcelData.salePrice = -1; | ||
356 | fullSimParcel.parcelData.parcelFlags = libsecondlife.Parcel.ParcelFlags.None; | ||
357 | fullSimParcel.parcelData.parcelStatus = libsecondlife.Parcel.ParcelStatus.Abandoned; | ||
388 | addParcel(fullSimParcel); | 358 | addParcel(fullSimParcel); |
389 | 359 | ||
390 | 360 | ||
391 | } | 361 | } |
392 | #endregion | 362 | #endregion |
393 | } | 363 | } |
394 | #endregion | 364 | #endregion |
395 | 365 | ||
396 | 366 | ||
397 | #region Parcel Class | 367 | #region Parcel Class |
368 | /// <summary> | ||
369 | /// Keeps track of a specific parcel's information | ||
370 | /// </summary> | ||
398 | public class Parcel | 371 | public class Parcel |
399 | { | 372 | { |
400 | #region Member Variables | 373 | #region Member Variables |
401 | private bool[,] parcelBitmap = new bool[64,64]; | 374 | public ParcelData parcelData = new ParcelData(); |
402 | public string parcelName = ""; | 375 | public World m_world; |
403 | public string parcelDesc = ""; | 376 | |
404 | public LLUUID ownerID = new LLUUID(); | 377 | private bool[,] parcelBitmap = new bool[64, 64]; |
405 | public bool isGroupOwned = false; | 378 | |
406 | public LLVector3 AABBMin = new LLVector3(); | ||
407 | public LLVector3 AABBMax = new LLVector3(); | ||
408 | public int area = 0; | ||
409 | public uint auctionID = 0; //Unemplemented. If set to 0, not being auctioned | ||
410 | public LLUUID authBuyerID = new LLUUID(); //Unemplemented. Authorized Buyer's UUID | ||
411 | public ParcelCategory category = new ParcelCategory(); //Unemplemented. Parcel's chosen category | ||
412 | public int claimDate = 0; //Unemplemented | ||
413 | public int claimPrice = 0; //Unemplemented | ||
414 | public LLUUID groupID = new LLUUID(); //Unemplemented | ||
415 | public int groupPrims = 0; //Unemplemented | ||
416 | public int salePrice = 0; //Unemeplemented. Parcels price. | ||
417 | public ParcelStatus parcelStatus = ParcelStatus.None; | ||
418 | public ParcelFlags parcelFlags = ParcelFlags.None; | ||
419 | |||
420 | private int localID; | ||
421 | private static int localIDCount = 0; | ||
422 | private World m_world; | ||
423 | #endregion | 379 | #endregion |
424 | 380 | ||
425 | 381 | ||
@@ -427,11 +383,8 @@ namespace OpenSim.world | |||
427 | public Parcel(LLUUID owner_id, bool is_group_owned, World world) | 383 | public Parcel(LLUUID owner_id, bool is_group_owned, World world) |
428 | { | 384 | { |
429 | m_world = world; | 385 | m_world = world; |
430 | ownerID = owner_id; | 386 | parcelData.ownerID = owner_id; |
431 | isGroupOwned = is_group_owned; | 387 | parcelData.isGroupOwned = is_group_owned; |
432 | |||
433 | localID = localIDCount; | ||
434 | localIDCount++; | ||
435 | 388 | ||
436 | } | 389 | } |
437 | #endregion | 390 | #endregion |
@@ -440,6 +393,12 @@ namespace OpenSim.world | |||
440 | #region Member Functions | 393 | #region Member Functions |
441 | 394 | ||
442 | #region General Functions | 395 | #region General Functions |
396 | /// <summary> | ||
397 | /// Checks to see if this parcel contains a point | ||
398 | /// </summary> | ||
399 | /// <param name="x"></param> | ||
400 | /// <param name="y"></param> | ||
401 | /// <returns>Returns true if the parcel contains the specified point</returns> | ||
443 | public bool containsPoint(int x, int y) | 402 | public bool containsPoint(int x, int y) |
444 | { | 403 | { |
445 | if (x >= 0 && y >= 0 && x <= 256 && x <= 256) | 404 | if (x >= 0 && y >= 0 && x <= 256 && x <= 256) |
@@ -455,39 +414,45 @@ namespace OpenSim.world | |||
455 | 414 | ||
456 | 415 | ||
457 | #region Packet Request Handling | 416 | #region Packet Request Handling |
417 | /// <summary> | ||
418 | /// Sends parcel properties as requested | ||
419 | /// </summary> | ||
420 | /// <param name="sequence_id">ID sent by client for them to keep track of</param> | ||
421 | /// <param name="snap_selection">Bool sent by client for them to use</param> | ||
422 | /// <param name="remote_client">Object representing the client</param> | ||
458 | public void sendParcelProperties(int sequence_id, bool snap_selection, ClientView remote_client) | 423 | public void sendParcelProperties(int sequence_id, bool snap_selection, ClientView remote_client) |
459 | { | 424 | { |
460 | 425 | ||
461 | ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); | 426 | ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); |
462 | updatePacket.ParcelData.AABBMax = AABBMax; | 427 | updatePacket.ParcelData.AABBMax = parcelData.AABBMax; |
463 | updatePacket.ParcelData.AABBMin = AABBMin; | 428 | updatePacket.ParcelData.AABBMin = parcelData.AABBMin; |
464 | updatePacket.ParcelData.Area = this.area; | 429 | updatePacket.ParcelData.Area = this.parcelData.area; |
465 | updatePacket.ParcelData.AuctionID = this.auctionID; | 430 | updatePacket.ParcelData.AuctionID = this.parcelData.auctionID; |
466 | updatePacket.ParcelData.AuthBuyerID = this.authBuyerID; //unemplemented | 431 | updatePacket.ParcelData.AuthBuyerID = this.parcelData.authBuyerID; //unemplemented |
467 | 432 | ||
468 | updatePacket.ParcelData.Bitmap = this.convertParcelBitmapToBytes(); | 433 | updatePacket.ParcelData.Bitmap = this.convertParcelBitmapToBytes(); |
469 | 434 | ||
470 | updatePacket.ParcelData.Desc = libsecondlife.Helpers.StringToField(this.parcelDesc); | 435 | updatePacket.ParcelData.Desc = libsecondlife.Helpers.StringToField(this.parcelData.parcelDesc); |
471 | updatePacket.ParcelData.Category = (byte)this.category; | 436 | updatePacket.ParcelData.Category = (byte)this.parcelData.category; |
472 | updatePacket.ParcelData.ClaimDate = this.claimDate; | 437 | updatePacket.ParcelData.ClaimDate = this.parcelData.claimDate; |
473 | updatePacket.ParcelData.ClaimPrice = this.claimPrice; | 438 | updatePacket.ParcelData.ClaimPrice = this.parcelData.claimPrice; |
474 | updatePacket.ParcelData.GroupID = this.groupID; | 439 | updatePacket.ParcelData.GroupID = this.parcelData.groupID; |
475 | updatePacket.ParcelData.GroupPrims = this.groupPrims; | 440 | updatePacket.ParcelData.GroupPrims = this.parcelData.groupPrims; |
476 | updatePacket.ParcelData.IsGroupOwned = this.isGroupOwned; | 441 | updatePacket.ParcelData.IsGroupOwned = this.parcelData.isGroupOwned; |
477 | updatePacket.ParcelData.LandingType = (byte)0; //unemplemented | 442 | updatePacket.ParcelData.LandingType = (byte)0; //unemplemented |
478 | updatePacket.ParcelData.LocalID = (byte)this.localID; | 443 | updatePacket.ParcelData.LocalID = (byte)this.parcelData.localID; |
479 | updatePacket.ParcelData.MaxPrims = 1000; //unemplemented | 444 | updatePacket.ParcelData.MaxPrims = 1000; //unemplemented |
480 | updatePacket.ParcelData.MediaAutoScale = (byte)0; //unemplemented | 445 | updatePacket.ParcelData.MediaAutoScale = (byte)0; //unemplemented |
481 | updatePacket.ParcelData.MediaID = LLUUID.Zero; //unemplemented | 446 | updatePacket.ParcelData.MediaID = LLUUID.Zero; //unemplemented |
482 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(""); //unemplemented | 447 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(""); //unemplemented |
483 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(""); //unemplemented | 448 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(""); //unemplemented |
484 | updatePacket.ParcelData.Name = Helpers.StringToField(this.parcelName); | 449 | updatePacket.ParcelData.Name = Helpers.StringToField(this.parcelData.parcelName); |
485 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented | 450 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented |
486 | updatePacket.ParcelData.OtherCount = 0; //unemplemented | 451 | updatePacket.ParcelData.OtherCount = 0; //unemplemented |
487 | updatePacket.ParcelData.OtherPrims = 0; //unemplented | 452 | updatePacket.ParcelData.OtherPrims = 0; //unemplented |
488 | updatePacket.ParcelData.OwnerID = this.ownerID; | 453 | updatePacket.ParcelData.OwnerID = this.parcelData.ownerID; |
489 | updatePacket.ParcelData.OwnerPrims = 0; //unemplemented | 454 | updatePacket.ParcelData.OwnerPrims = 0; //unemplemented |
490 | updatePacket.ParcelData.ParcelFlags = (uint)this.parcelFlags; //unemplemented | 455 | updatePacket.ParcelData.ParcelFlags = (uint)this.parcelData.parcelFlags; //unemplemented |
491 | updatePacket.ParcelData.ParcelPrimBonus = (float)1.0; //unemplemented | 456 | updatePacket.ParcelData.ParcelPrimBonus = (float)1.0; //unemplemented |
492 | updatePacket.ParcelData.PassHours = (float)0.0; //unemplemented | 457 | updatePacket.ParcelData.PassHours = (float)0.0; //unemplemented |
493 | updatePacket.ParcelData.PassPrice = 0; //unemeplemented | 458 | updatePacket.ParcelData.PassPrice = 0; //unemeplemented |
@@ -498,7 +463,7 @@ namespace OpenSim.world | |||
498 | updatePacket.ParcelData.RegionPushOverride = true; //unemplemented | 463 | updatePacket.ParcelData.RegionPushOverride = true; //unemplemented |
499 | updatePacket.ParcelData.RentPrice = 0; //?? | 464 | updatePacket.ParcelData.RentPrice = 0; //?? |
500 | updatePacket.ParcelData.RequestResult = 0;//?? | 465 | updatePacket.ParcelData.RequestResult = 0;//?? |
501 | updatePacket.ParcelData.SalePrice = this.salePrice; //unemplemented | 466 | updatePacket.ParcelData.SalePrice = this.parcelData.salePrice; //unemplemented |
502 | updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented | 467 | updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented |
503 | updatePacket.ParcelData.SelfCount = 0;//unemplemented | 468 | updatePacket.ParcelData.SelfCount = 0;//unemplemented |
504 | updatePacket.ParcelData.SequenceID = sequence_id; | 469 | updatePacket.ParcelData.SequenceID = sequence_id; |
@@ -506,17 +471,20 @@ namespace OpenSim.world | |||
506 | updatePacket.ParcelData.SimWideTotalPrims = 0; //unemplemented | 471 | updatePacket.ParcelData.SimWideTotalPrims = 0; //unemplemented |
507 | updatePacket.ParcelData.SnapSelection = snap_selection; //Bleh - not important yet | 472 | updatePacket.ParcelData.SnapSelection = snap_selection; //Bleh - not important yet |
508 | updatePacket.ParcelData.SnapshotID = LLUUID.Zero; //Unemplemented | 473 | updatePacket.ParcelData.SnapshotID = LLUUID.Zero; //Unemplemented |
509 | updatePacket.ParcelData.Status = (byte)this.parcelStatus; //?? | 474 | updatePacket.ParcelData.Status = (byte)this.parcelData.parcelStatus; //?? |
510 | updatePacket.ParcelData.TotalPrims = 0; //unemplemented | 475 | updatePacket.ParcelData.TotalPrims = 0; //unemplemented |
511 | updatePacket.ParcelData.UserLocation = LLVector3.Zero; //unemplemented | 476 | updatePacket.ParcelData.UserLocation = LLVector3.Zero; //unemplemented |
512 | updatePacket.ParcelData.UserLookAt = LLVector3.Zero; //unemeplemented | 477 | updatePacket.ParcelData.UserLookAt = LLVector3.Zero; //unemeplemented |
513 | 478 | ||
514 | remote_client.OutPacket((Packet)updatePacket); | 479 | remote_client.OutPacket((Packet)updatePacket); |
515 | } | 480 | } |
516 | #endregion | 481 | #endregion |
517 | 482 | ||
518 | 483 | ||
519 | #region Update Functions | 484 | #region Update Functions |
485 | /// <summary> | ||
486 | /// Updates the AABBMin and AABBMax values after area/shape modification of parcel | ||
487 | /// </summary> | ||
520 | private void updateAABBAndAreaValues() | 488 | private void updateAABBAndAreaValues() |
521 | { | 489 | { |
522 | int min_x = 64; | 490 | int min_x = 64; |
@@ -539,14 +507,27 @@ namespace OpenSim.world | |||
539 | } | 507 | } |
540 | } | 508 | } |
541 | } | 509 | } |
542 | this.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), m_world.Terrain[(min_x * 4), (min_y * 4)]); | 510 | this.parcelData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), m_world.Terrain[(min_x * 4), (min_y * 4)]); |
543 | this.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), m_world.Terrain[(max_x * 4), (max_y * 4)]); | 511 | this.parcelData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), m_world.Terrain[(max_x * 4), (max_y * 4)]); |
544 | this.area = tempArea; | 512 | this.parcelData.area = tempArea; |
513 | } | ||
514 | |||
515 | public void updateParcelBitmapByteArray() | ||
516 | { | ||
517 | parcelData.parcelBitmapByteArray = convertParcelBitmapToBytes(); | ||
518 | } | ||
519 | public void setParcelBitmapFromByteArray() | ||
520 | { | ||
521 | parcelBitmap = convertBytesToParcelBitmap(); | ||
545 | } | 522 | } |
546 | #endregion | 523 | #endregion |
547 | 524 | ||
548 | 525 | ||
549 | #region Parcel Bitmap Functions | 526 | #region Parcel Bitmap Functions |
527 | /// <summary> | ||
528 | /// Sets the parcel's bitmap manually | ||
529 | /// </summary> | ||
530 | /// <param name="bitmap">64x64 block representing where this parcel is on a map</param> | ||
550 | public void setParcelBitmap(bool[,] bitmap) | 531 | public void setParcelBitmap(bool[,] bitmap) |
551 | { | 532 | { |
552 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | 533 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) |
@@ -559,23 +540,32 @@ namespace OpenSim.world | |||
559 | //Valid: Lets set it | 540 | //Valid: Lets set it |
560 | this.parcelBitmap = bitmap; | 541 | this.parcelBitmap = bitmap; |
561 | updateAABBAndAreaValues(); | 542 | updateAABBAndAreaValues(); |
543 | updateParcelBitmapByteArray(); | ||
562 | } | 544 | } |
563 | } | 545 | } |
546 | /// <summary> | ||
547 | /// Gets the parcels bitmap manually | ||
548 | /// </summary> | ||
549 | /// <returns></returns> | ||
564 | public bool[,] getParcelBitmap() | 550 | public bool[,] getParcelBitmap() |
565 | { | 551 | { |
566 | return parcelBitmap; | 552 | return parcelBitmap; |
567 | } | 553 | } |
554 | /// <summary> | ||
555 | /// Converts the parcel bitmap to a packet friendly byte array | ||
556 | /// </summary> | ||
557 | /// <returns></returns> | ||
568 | private byte[] convertParcelBitmapToBytes() | 558 | private byte[] convertParcelBitmapToBytes() |
569 | { | 559 | { |
570 | byte[] tempConvertArr = new byte[64 * 64 / 8]; | 560 | byte[] tempConvertArr = new byte[64 * 64 / 8]; |
571 | byte tempByte = 0; | 561 | byte tempByte = 0; |
572 | int x, y,i, byteNum = 0; | 562 | int x, y, i, byteNum = 0; |
573 | i = 0; | 563 | i = 0; |
574 | for (x = 0; x < 64; x++) | 564 | for (y = 0; y < 64; y++) |
575 | { | 565 | { |
576 | for (y = 0; y < 64; y++) | 566 | for (x = 0; x < 64; x++) |
577 | { | 567 | { |
578 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x,y]) << (i++ % 8)); | 568 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x, y]) << (i++ % 8)); |
579 | if (i % 8 == 0) | 569 | if (i % 8 == 0) |
580 | { | 570 | { |
581 | tempConvertArr[byteNum] = tempByte; | 571 | tempConvertArr[byteNum] = tempByte; |
@@ -585,14 +575,44 @@ namespace OpenSim.world | |||
585 | } | 575 | } |
586 | } | 576 | } |
587 | } | 577 | } |
588 | tempByte.ToString(); | ||
589 | return tempConvertArr; | 578 | return tempConvertArr; |
590 | } | 579 | } |
591 | 580 | ||
581 | private bool[,] convertBytesToParcelBitmap() | ||
582 | { | ||
583 | bool[,] tempConvertMap = new bool[64, 64]; | ||
584 | |||
585 | byte tempByte = 0; | ||
586 | int x = 0, y = 0, i = 0, bitNum = 0; | ||
587 | for(i = 0; i < 512; i++) | ||
588 | { | ||
589 | tempByte = parcelData.parcelBitmapByteArray[i]; | ||
590 | for(bitNum = 7; bitNum >= 0; bitNum--) | ||
591 | { | ||
592 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1); | ||
593 | tempConvertMap[x, y] = bit; | ||
594 | if (x >= 64) y++; | ||
595 | } | ||
596 | } | ||
597 | return tempConvertMap; | ||
598 | } | ||
599 | /// <summary> | ||
600 | /// Full sim parcel creation | ||
601 | /// </summary> | ||
602 | /// <returns></returns> | ||
592 | public static bool[,] basicFullRegionParcelBitmap() | 603 | public static bool[,] basicFullRegionParcelBitmap() |
593 | { | 604 | { |
594 | return getSquareParcelBitmap(0, 0, 256, 256); | 605 | return getSquareParcelBitmap(0, 0, 256, 256); |
595 | } | 606 | } |
607 | |||
608 | /// <summary> | ||
609 | /// Used to modify the bitmap between the x and y points. Points use 64 scale | ||
610 | /// </summary> | ||
611 | /// <param name="start_x"></param> | ||
612 | /// <param name="start_y"></param> | ||
613 | /// <param name="end_x"></param> | ||
614 | /// <param name="end_y"></param> | ||
615 | /// <returns></returns> | ||
596 | public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y) | 616 | public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y) |
597 | { | 617 | { |
598 | 618 | ||
@@ -602,6 +622,17 @@ namespace OpenSim.world | |||
602 | tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_x, true); | 622 | tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_x, true); |
603 | return tempBitmap; | 623 | return tempBitmap; |
604 | } | 624 | } |
625 | |||
626 | /// <summary> | ||
627 | /// Change a parcel's bitmap at within a square and set those points to a specific value | ||
628 | /// </summary> | ||
629 | /// <param name="parcel_bitmap"></param> | ||
630 | /// <param name="start_x"></param> | ||
631 | /// <param name="start_y"></param> | ||
632 | /// <param name="end_x"></param> | ||
633 | /// <param name="end_y"></param> | ||
634 | /// <param name="set_value"></param> | ||
635 | /// <returns></returns> | ||
605 | public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) | 636 | public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) |
606 | { | 637 | { |
607 | if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2) | 638 | if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2) |
@@ -624,6 +655,12 @@ namespace OpenSim.world | |||
624 | } | 655 | } |
625 | return parcel_bitmap; | 656 | return parcel_bitmap; |
626 | } | 657 | } |
658 | /// <summary> | ||
659 | /// Join the true values of 2 bitmaps together | ||
660 | /// </summary> | ||
661 | /// <param name="bitmap_base"></param> | ||
662 | /// <param name="bitmap_add"></param> | ||
663 | /// <returns></returns> | ||
627 | public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | 664 | public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) |
628 | { | 665 | { |
629 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | 666 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) |
@@ -642,7 +679,7 @@ namespace OpenSim.world | |||
642 | { | 679 | { |
643 | for (y = 0; y < 64; y++) | 680 | for (y = 0; y < 64; y++) |
644 | { | 681 | { |
645 | if (bitmap_add[x,y]) | 682 | if (bitmap_add[x, y]) |
646 | { | 683 | { |
647 | bitmap_base[x, y] = true; | 684 | bitmap_base[x, y] = true; |
648 | } | 685 | } |
@@ -653,6 +690,10 @@ namespace OpenSim.world | |||
653 | #endregion | 690 | #endregion |
654 | 691 | ||
655 | #endregion | 692 | #endregion |
693 | |||
694 | |||
656 | } | 695 | } |
657 | #endregion | 696 | #endregion |
697 | |||
698 | |||
658 | } | 699 | } |