diff options
Diffstat (limited to 'OpenSim/OpenSim.RegionServer/world')
-rw-r--r-- | OpenSim/OpenSim.RegionServer/world/ParcelManager.cs | 658 |
1 files changed, 658 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs new file mode 100644 index 0000000..7cc39ff --- /dev/null +++ b/OpenSim/OpenSim.RegionServer/world/ParcelManager.cs | |||
@@ -0,0 +1,658 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using libsecondlife; | ||
5 | using libsecondlife.Packets; | ||
6 | |||
7 | namespace OpenSim.world | ||
8 | { | ||
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); | ||
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 | |||
80 | /// <summary> | ||
81 | /// Parcel ownership status | ||
82 | /// </summary> | ||
83 | public enum ParcelStatus : sbyte | ||
84 | { | ||
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 | |||
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 | ||
136 | //Parcel types set with flags in ParcelOverlay. | ||
137 | //Only one of these can be used. | ||
138 | public static byte PARCEL_TYPE_PUBLIC = (byte)0; //Equals 00000000 | ||
139 | 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 | ||
141 | 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 | ||
143 | public static byte PARCEL_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 | ||
144 | |||
145 | |||
146 | //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) | ||
148 | //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 | ||
150 | public static byte PARCEL_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 | ||
151 | |||
152 | #endregion | ||
153 | |||
154 | #region Member Variables | ||
155 | private List<Parcel> parcelList; | ||
156 | private static World m_world; | ||
157 | #endregion | ||
158 | |||
159 | #region Constructors | ||
160 | public ParcelManager(World world) | ||
161 | { | ||
162 | parcelList = new List<Parcel>(); | ||
163 | 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"); | ||
169 | |||
170 | |||
171 | } | ||
172 | #endregion | ||
173 | |||
174 | #region Member Functions | ||
175 | |||
176 | #region Parcel Add/Remove/Get | ||
177 | public void addParcel(Parcel new_parcel) | ||
178 | { | ||
179 | parcelList.Add(new_parcel); | ||
180 | } | ||
181 | public void removeParcel(Parcel old_parcel) | ||
182 | { | ||
183 | parcelList.Remove(old_parcel); | ||
184 | } | ||
185 | public Parcel getParcel(int x, int y) | ||
186 | { | ||
187 | int searchParcel; | ||
188 | for(searchParcel = 0; searchParcel < this.parcelList.Count; searchParcel++) | ||
189 | { | ||
190 | if(parcelList[searchParcel].containsPoint(x,y)) | ||
191 | { | ||
192 | return this.parcelList[searchParcel]; | ||
193 | } | ||
194 | } | ||
195 | throw new Exception("Error: Parcel not found at point " + x + ", " + y); | ||
196 | |||
197 | } | ||
198 | #endregion | ||
199 | |||
200 | #region Parcel Modification | ||
201 | public bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | ||
202 | { | ||
203 | //First, lets loop through the points and make sure they are all in the same parcel | ||
204 | //Get the parcel at start | ||
205 | Parcel startParcel = getParcel(start_x, start_y); | ||
206 | if(startParcel == null) return false; //No such parcel at the beginning | ||
207 | |||
208 | //Loop through the points | ||
209 | try | ||
210 | { | ||
211 | int totalX = end_x - start_x; | ||
212 | int totalY = end_y - start_y; | ||
213 | int x, y; | ||
214 | for (x = 0; x < totalX; x++) | ||
215 | { | ||
216 | for (y = 0; y < totalY; y++) | ||
217 | { | ||
218 | Parcel tempParcel = getParcel(start_x + x, start_y + y); | ||
219 | if (tempParcel == null) return false; //No such parcel at that point | ||
220 | if (tempParcel != startParcel) return false; //Subdividing over 2 parcels; no-no | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | catch (Exception e) | ||
225 | { | ||
226 | return false; //Exception. For now, lets skip subdivision | ||
227 | } | ||
228 | |||
229 | //If we are still here, then they are subdividing within one parcel | ||
230 | //Check owner | ||
231 | if (startParcel.ownerID != attempting_user_id) | ||
232 | { | ||
233 | return false; //They cant do this! | ||
234 | } | ||
235 | |||
236 | //Lets create a new parcel with bitmap activated at that point (keeping the old parcels info) | ||
237 | Parcel newParcel = startParcel; | ||
238 | newParcel.setParcelBitmap(Parcel.getSquareParcelBitmap(start_x, start_y, end_x, end_y)); | ||
239 | |||
240 | //Now, lets set the subdivision area of the original to false | ||
241 | int startParcelIndex = parcelList.IndexOf(startParcel); | ||
242 | parcelList[startParcelIndex].setParcelBitmap(Parcel.modifyParcelBitmapSquare(parcelList[startParcelIndex].getParcelBitmap(),start_x,start_y,end_x, end_y,false)); | ||
243 | |||
244 | //Now add the new parcel | ||
245 | addParcel(newParcel); | ||
246 | |||
247 | return true; | ||
248 | } | ||
249 | |||
250 | public bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) | ||
251 | { | ||
252 | //NOTE: The following only connects the parcels in each corner and not all the parcels that are within the selection box! | ||
253 | //This should be fixed later -- somewhat "incomplete code" --Ming | ||
254 | Parcel startParcel, endParcel; | ||
255 | try | ||
256 | { | ||
257 | startParcel = getParcel(start_x, start_y); | ||
258 | endParcel = getParcel(end_x, end_y); | ||
259 | } | ||
260 | catch (Exception e) | ||
261 | { | ||
262 | return false; //Error occured when trying to get the start and end parcels | ||
263 | } | ||
264 | //Check the parcel owners: | ||
265 | if (startParcel.ownerID != endParcel.ownerID) | ||
266 | { | ||
267 | return false; | ||
268 | } | ||
269 | if (startParcel.ownerID != attempting_user_id) | ||
270 | { | ||
271 | //TODO: Group editing stuff. Avatar owner support for now | ||
272 | return false; | ||
273 | } | ||
274 | |||
275 | //Same owners! Lets join them | ||
276 | //Merge them to startParcel | ||
277 | parcelList[parcelList.IndexOf(startParcel)].setParcelBitmap(Parcel.mergeParcelBitmaps(startParcel.getParcelBitmap(),endParcel.getParcelBitmap())); | ||
278 | |||
279 | //Remove the old parcel | ||
280 | parcelList.Remove(endParcel); | ||
281 | |||
282 | return true; | ||
283 | |||
284 | |||
285 | |||
286 | } | ||
287 | #endregion | ||
288 | |||
289 | #region Parcel Updating | ||
290 | /// <summary> | ||
291 | /// Where we send the ParcelOverlay packet to the client | ||
292 | /// </summary> | ||
293 | /// <param name="remote_client">The object representing the client</param> | ||
294 | public void sendParcelOverlay(ClientView remote_client) | ||
295 | { | ||
296 | const int PARCEL_BLOCKS_PER_PACKET = 1024; | ||
297 | int x, y = 0; | ||
298 | byte[] byteArray = new byte[PARCEL_BLOCKS_PER_PACKET]; | ||
299 | int byteArrayCount = 0; | ||
300 | int sequenceID = 0; | ||
301 | ParcelOverlayPacket packet; | ||
302 | |||
303 | for (x = 0; x < 64; x++) | ||
304 | { | ||
305 | for (y = 0; y < 64; y++) | ||
306 | { | ||
307 | byte tempByte = (byte)0; //This represents the byte for the current 4x4 | ||
308 | Parcel currentParcelBlock = getParcel(x * 4, y * 4); | ||
309 | |||
310 | if (currentParcelBlock.ownerID == remote_client.AgentID) | ||
311 | { | ||
312 | //Owner Flag | ||
313 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_REQUESTER); | ||
314 | } | ||
315 | else if (currentParcelBlock.salePrice > 0 && (currentParcelBlock.authBuyerID == LLUUID.Zero || currentParcelBlock.authBuyerID == remote_client.AgentID)) | ||
316 | { | ||
317 | //Sale Flag | ||
318 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_IS_FOR_SALE); | ||
319 | } | ||
320 | else if (currentParcelBlock.ownerID == LLUUID.Zero) | ||
321 | { | ||
322 | //Public Flag | ||
323 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_PUBLIC); | ||
324 | } | ||
325 | else | ||
326 | { | ||
327 | //Other Flag | ||
328 | tempByte = Convert.ToByte(tempByte | PARCEL_TYPE_OWNED_BY_OTHER); | ||
329 | } | ||
330 | |||
331 | |||
332 | //Now for border control | ||
333 | if (x == 0) | ||
334 | { | ||
335 | tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_WEST); | ||
336 | } | ||
337 | else if (getParcel(x - 1, y) != currentParcelBlock) | ||
338 | { | ||
339 | tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_WEST); | ||
340 | } | ||
341 | |||
342 | if (y == 0) | ||
343 | { | ||
344 | tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_SOUTH); | ||
345 | } | ||
346 | else if (getParcel(x, y - 1) != currentParcelBlock) | ||
347 | { | ||
348 | tempByte = Convert.ToByte(tempByte | PARCEL_FLAG_PROPERTY_BORDER_SOUTH); | ||
349 | } | ||
350 | |||
351 | byteArray[byteArrayCount] = tempByte; | ||
352 | byteArrayCount++; | ||
353 | if (byteArrayCount >= PARCEL_BLOCKS_PER_PACKET) | ||
354 | { | ||
355 | byteArrayCount = 0; | ||
356 | packet = new ParcelOverlayPacket(); | ||
357 | packet.ParcelData.Data = byteArray; | ||
358 | packet.ParcelData.SequenceID = sequenceID; | ||
359 | remote_client.OutPacket((Packet)packet); | ||
360 | sequenceID++; | ||
361 | byteArray = new byte[PARCEL_BLOCKS_PER_PACKET]; | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | |||
366 | packet = new ParcelOverlayPacket(); | ||
367 | packet.ParcelData.Data = byteArray; | ||
368 | packet.ParcelData.SequenceID = sequenceID; //Eh? | ||
369 | remote_client.OutPacket((Packet)packet); | ||
370 | } | ||
371 | #endregion | ||
372 | public void resetSimParcels() | ||
373 | { | ||
374 | //Remove all the parcels in the sim and add a blank, full sim parcel set to public | ||
375 | parcelList.Clear(); | ||
376 | Parcel fullSimParcel = new Parcel(LLUUID.Zero, false,m_world); | ||
377 | fullSimParcel.setParcelBitmap(Parcel.basicFullRegionParcelBitmap()); | ||
378 | fullSimParcel.parcelName = "Your Sim Parcel"; | ||
379 | fullSimParcel.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 | |||
388 | addParcel(fullSimParcel); | ||
389 | |||
390 | |||
391 | } | ||
392 | #endregion | ||
393 | } | ||
394 | #endregion | ||
395 | |||
396 | |||
397 | #region Parcel Class | ||
398 | public class Parcel | ||
399 | { | ||
400 | #region Member Variables | ||
401 | private bool[,] parcelBitmap = new bool[64,64]; | ||
402 | public string parcelName = ""; | ||
403 | public string parcelDesc = ""; | ||
404 | public LLUUID ownerID = new LLUUID(); | ||
405 | public bool isGroupOwned = false; | ||
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 | ||
424 | |||
425 | |||
426 | #region Constructors | ||
427 | public Parcel(LLUUID owner_id, bool is_group_owned, World world) | ||
428 | { | ||
429 | m_world = world; | ||
430 | ownerID = owner_id; | ||
431 | isGroupOwned = is_group_owned; | ||
432 | |||
433 | localID = localIDCount; | ||
434 | localIDCount++; | ||
435 | |||
436 | } | ||
437 | #endregion | ||
438 | |||
439 | |||
440 | #region Member Functions | ||
441 | |||
442 | #region General Functions | ||
443 | public bool containsPoint(int x, int y) | ||
444 | { | ||
445 | if (x >= 0 && y >= 0 && x <= 256 && x <= 256) | ||
446 | { | ||
447 | return (this.parcelBitmap[x / 4, y / 4] == true); | ||
448 | } | ||
449 | else | ||
450 | { | ||
451 | return false; | ||
452 | } | ||
453 | } | ||
454 | #endregion | ||
455 | |||
456 | |||
457 | #region Packet Request Handling | ||
458 | public void sendParcelProperties(int sequence_id, bool snap_selection, ClientView remote_client) | ||
459 | { | ||
460 | |||
461 | ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); | ||
462 | updatePacket.ParcelData.AABBMax = AABBMax; | ||
463 | updatePacket.ParcelData.AABBMin = AABBMin; | ||
464 | updatePacket.ParcelData.Area = this.area; | ||
465 | updatePacket.ParcelData.AuctionID = this.auctionID; | ||
466 | updatePacket.ParcelData.AuthBuyerID = this.authBuyerID; //unemplemented | ||
467 | |||
468 | updatePacket.ParcelData.Bitmap = this.convertParcelBitmapToBytes(); | ||
469 | |||
470 | updatePacket.ParcelData.Desc = libsecondlife.Helpers.StringToField(this.parcelDesc); | ||
471 | updatePacket.ParcelData.Category = (byte)this.category; | ||
472 | updatePacket.ParcelData.ClaimDate = this.claimDate; | ||
473 | updatePacket.ParcelData.ClaimPrice = this.claimPrice; | ||
474 | updatePacket.ParcelData.GroupID = this.groupID; | ||
475 | updatePacket.ParcelData.GroupPrims = this.groupPrims; | ||
476 | updatePacket.ParcelData.IsGroupOwned = this.isGroupOwned; | ||
477 | updatePacket.ParcelData.LandingType = (byte)0; //unemplemented | ||
478 | updatePacket.ParcelData.LocalID = (byte)this.localID; | ||
479 | updatePacket.ParcelData.MaxPrims = 1000; //unemplemented | ||
480 | updatePacket.ParcelData.MediaAutoScale = (byte)0; //unemplemented | ||
481 | updatePacket.ParcelData.MediaID = LLUUID.Zero; //unemplemented | ||
482 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(""); //unemplemented | ||
483 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(""); //unemplemented | ||
484 | updatePacket.ParcelData.Name = Helpers.StringToField(this.parcelName); | ||
485 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented | ||
486 | updatePacket.ParcelData.OtherCount = 0; //unemplemented | ||
487 | updatePacket.ParcelData.OtherPrims = 0; //unemplented | ||
488 | updatePacket.ParcelData.OwnerID = this.ownerID; | ||
489 | updatePacket.ParcelData.OwnerPrims = 0; //unemplemented | ||
490 | updatePacket.ParcelData.ParcelFlags = (uint)this.parcelFlags; //unemplemented | ||
491 | updatePacket.ParcelData.ParcelPrimBonus = (float)1.0; //unemplemented | ||
492 | updatePacket.ParcelData.PassHours = (float)0.0; //unemplemented | ||
493 | updatePacket.ParcelData.PassPrice = 0; //unemeplemented | ||
494 | updatePacket.ParcelData.PublicCount = 0; //unemplemented | ||
495 | updatePacket.ParcelData.RegionDenyAnonymous = false; //unemplemented | ||
496 | updatePacket.ParcelData.RegionDenyIdentified = false; //unemplemented | ||
497 | updatePacket.ParcelData.RegionDenyTransacted = false; //unemplemented | ||
498 | updatePacket.ParcelData.RegionPushOverride = true; //unemplemented | ||
499 | updatePacket.ParcelData.RentPrice = 0; //?? | ||
500 | updatePacket.ParcelData.RequestResult = 0;//?? | ||
501 | updatePacket.ParcelData.SalePrice = this.salePrice; //unemplemented | ||
502 | updatePacket.ParcelData.SelectedPrims = 0; //unemeplemented | ||
503 | updatePacket.ParcelData.SelfCount = 0;//unemplemented | ||
504 | updatePacket.ParcelData.SequenceID = sequence_id; | ||
505 | updatePacket.ParcelData.SimWideMaxPrims = 15000; //unemplemented | ||
506 | updatePacket.ParcelData.SimWideTotalPrims = 0; //unemplemented | ||
507 | updatePacket.ParcelData.SnapSelection = snap_selection; //Bleh - not important yet | ||
508 | updatePacket.ParcelData.SnapshotID = LLUUID.Zero; //Unemplemented | ||
509 | updatePacket.ParcelData.Status = (byte)this.parcelStatus; //?? | ||
510 | updatePacket.ParcelData.TotalPrims = 0; //unemplemented | ||
511 | updatePacket.ParcelData.UserLocation = LLVector3.Zero; //unemplemented | ||
512 | updatePacket.ParcelData.UserLookAt = LLVector3.Zero; //unemeplemented | ||
513 | |||
514 | remote_client.OutPacket((Packet)updatePacket); | ||
515 | } | ||
516 | #endregion | ||
517 | |||
518 | |||
519 | #region Update Functions | ||
520 | private void updateAABBAndAreaValues() | ||
521 | { | ||
522 | int min_x = 64; | ||
523 | int min_y = 64; | ||
524 | int max_x = 0; | ||
525 | int max_y = 0; | ||
526 | int tempArea = 0; | ||
527 | int x, y; | ||
528 | for (x = 0; x < 64; x++) | ||
529 | { | ||
530 | for (y = 0; y < 64; y++) | ||
531 | { | ||
532 | if (parcelBitmap[x, y] == true) | ||
533 | { | ||
534 | if (min_x > x) min_x = x; | ||
535 | if (min_y > y) min_y = y; | ||
536 | if (max_x < x) max_x = x; | ||
537 | if (max_y < y) max_y = y; | ||
538 | tempArea += 16; //16sqm parcel | ||
539 | } | ||
540 | } | ||
541 | } | ||
542 | this.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)]); | ||
544 | this.area = tempArea; | ||
545 | } | ||
546 | #endregion | ||
547 | |||
548 | |||
549 | #region Parcel Bitmap Functions | ||
550 | public void setParcelBitmap(bool[,] bitmap) | ||
551 | { | ||
552 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | ||
553 | { | ||
554 | //Throw an exception - The bitmap is not 64x64 | ||
555 | throw new Exception("Error: Invalid Parcel Bitmap"); | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | //Valid: Lets set it | ||
560 | this.parcelBitmap = bitmap; | ||
561 | updateAABBAndAreaValues(); | ||
562 | } | ||
563 | } | ||
564 | public bool[,] getParcelBitmap() | ||
565 | { | ||
566 | return parcelBitmap; | ||
567 | } | ||
568 | private byte[] convertParcelBitmapToBytes() | ||
569 | { | ||
570 | byte[] tempConvertArr = new byte[64 * 64 / 8]; | ||
571 | byte tempByte = 0; | ||
572 | int x, y,i, byteNum = 0; | ||
573 | i = 0; | ||
574 | for (x = 0; x < 64; x++) | ||
575 | { | ||
576 | for (y = 0; y < 64; y++) | ||
577 | { | ||
578 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(parcelBitmap[x,y]) << (i++ % 8)); | ||
579 | if (i % 8 == 0) | ||
580 | { | ||
581 | tempConvertArr[byteNum] = tempByte; | ||
582 | tempByte = (byte)0; | ||
583 | i = 0; | ||
584 | byteNum++; | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | tempByte.ToString(); | ||
589 | return tempConvertArr; | ||
590 | } | ||
591 | |||
592 | public static bool[,] basicFullRegionParcelBitmap() | ||
593 | { | ||
594 | return getSquareParcelBitmap(0, 0, 256, 256); | ||
595 | } | ||
596 | public static bool[,] getSquareParcelBitmap(int start_x, int start_y, int end_x, int end_y) | ||
597 | { | ||
598 | |||
599 | bool[,] tempBitmap = new bool[64, 64]; | ||
600 | tempBitmap.Initialize(); | ||
601 | |||
602 | tempBitmap = modifyParcelBitmapSquare(tempBitmap, start_x, start_y, end_x, end_x, true); | ||
603 | return tempBitmap; | ||
604 | } | ||
605 | public static bool[,] modifyParcelBitmapSquare(bool[,] parcel_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) | ||
606 | { | ||
607 | if (parcel_bitmap.GetLength(0) != 64 || parcel_bitmap.GetLength(1) != 64 || parcel_bitmap.Rank != 2) | ||
608 | { | ||
609 | //Throw an exception - The bitmap is not 64x64 | ||
610 | throw new Exception("Error: Invalid Parcel Bitmap in modifyParcelBitmapSquare()"); | ||
611 | } | ||
612 | |||
613 | int x, y; | ||
614 | for (x = 0; x < 64; x++) | ||
615 | { | ||
616 | for (y = 0; y < 64; y++) | ||
617 | { | ||
618 | if (x >= start_x / 4 && x <= end_x / 4 | ||
619 | && y >= start_y / 4 && y <= end_y / 4) | ||
620 | { | ||
621 | parcel_bitmap[x, y] = true; | ||
622 | } | ||
623 | } | ||
624 | } | ||
625 | return parcel_bitmap; | ||
626 | } | ||
627 | public static bool[,] mergeParcelBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | ||
628 | { | ||
629 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | ||
630 | { | ||
631 | //Throw an exception - The bitmap is not 64x64 | ||
632 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeParcelBitmaps"); | ||
633 | } | ||
634 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) | ||
635 | { | ||
636 | //Throw an exception - The bitmap is not 64x64 | ||
637 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeParcelBitmaps"); | ||
638 | } | ||
639 | |||
640 | int x, y; | ||
641 | for (x = 0; x < 64; x++) | ||
642 | { | ||
643 | for (y = 0; y < 64; y++) | ||
644 | { | ||
645 | if (bitmap_add[x,y]) | ||
646 | { | ||
647 | bitmap_base[x, y] = true; | ||
648 | } | ||
649 | } | ||
650 | } | ||
651 | return bitmap_base; | ||
652 | } | ||
653 | #endregion | ||
654 | |||
655 | #endregion | ||
656 | } | ||
657 | #endregion | ||
658 | } | ||