diff options
Diffstat (limited to 'OpenSim/Region/Environment/LandManagement/Land.cs')
-rw-r--r-- | OpenSim/Region/Environment/LandManagement/Land.cs | 842 |
1 files changed, 0 insertions, 842 deletions
diff --git a/OpenSim/Region/Environment/LandManagement/Land.cs b/OpenSim/Region/Environment/LandManagement/Land.cs deleted file mode 100644 index 5b84103..0000000 --- a/OpenSim/Region/Environment/LandManagement/Land.cs +++ /dev/null | |||
@@ -1,842 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
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 | ||
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 | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using libsecondlife.Packets; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Console; | ||
34 | using OpenSim.Region.Environment.Scenes; | ||
35 | using OpenSim.Region.Environment.Interfaces; | ||
36 | |||
37 | namespace OpenSim.Region.Environment.LandManagement | ||
38 | { | ||
39 | |||
40 | #region Parcel Class | ||
41 | |||
42 | /// <summary> | ||
43 | /// Keeps track of a specific piece of land's information | ||
44 | /// </summary> | ||
45 | public class Land | ||
46 | { | ||
47 | #region Member Variables | ||
48 | |||
49 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | public LandData landData = new LandData(); | ||
52 | public List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); | ||
53 | public Scene m_scene; | ||
54 | |||
55 | private bool[,] landBitmap = new bool[64,64]; | ||
56 | |||
57 | #endregion | ||
58 | |||
59 | #region Constructors | ||
60 | |||
61 | public Land(LLUUID owner_id, bool is_group_owned, Scene scene) | ||
62 | { | ||
63 | m_scene = scene; | ||
64 | landData.ownerID = owner_id; | ||
65 | landData.isGroupOwned = is_group_owned; | ||
66 | } | ||
67 | |||
68 | #endregion | ||
69 | |||
70 | #region Member Functions | ||
71 | |||
72 | #region General Functions | ||
73 | |||
74 | /// <summary> | ||
75 | /// Checks to see if this land object contains a point | ||
76 | /// </summary> | ||
77 | /// <param name="x"></param> | ||
78 | /// <param name="y"></param> | ||
79 | /// <returns>Returns true if the piece of land contains the specified point</returns> | ||
80 | public bool containsPoint(int x, int y) | ||
81 | { | ||
82 | if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) | ||
83 | { | ||
84 | return (landBitmap[x/4, y/4] == true); | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | return false; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | public Land Copy() | ||
93 | { | ||
94 | Land newLand = new Land(landData.ownerID, landData.isGroupOwned, m_scene); | ||
95 | |||
96 | //Place all new variables here! | ||
97 | newLand.landBitmap = (bool[,]) (landBitmap.Clone()); | ||
98 | newLand.landData = landData.Copy(); | ||
99 | |||
100 | return newLand; | ||
101 | } | ||
102 | |||
103 | #endregion | ||
104 | |||
105 | #region Packet Request Handling | ||
106 | |||
107 | /// <summary> | ||
108 | /// Sends land properties as requested | ||
109 | /// </summary> | ||
110 | /// <param name="sequence_id">ID sent by client for them to keep track of</param> | ||
111 | /// <param name="snap_selection">Bool sent by client for them to use</param> | ||
112 | /// <param name="remote_client">Object representing the client</param> | ||
113 | public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, | ||
114 | IClientAPI remote_client) | ||
115 | { | ||
116 | ParcelPropertiesPacket updatePacket = (ParcelPropertiesPacket) PacketPool.Instance.GetPacket(PacketType.ParcelProperties); | ||
117 | // TODO: don't create new blocks if recycling an old packet | ||
118 | |||
119 | updatePacket.ParcelData.AABBMax = landData.AABBMax; | ||
120 | updatePacket.ParcelData.AABBMin = landData.AABBMin; | ||
121 | updatePacket.ParcelData.Area = landData.area; | ||
122 | updatePacket.ParcelData.AuctionID = landData.auctionID; | ||
123 | updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented | ||
124 | |||
125 | updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; | ||
126 | |||
127 | updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); | ||
128 | updatePacket.ParcelData.Category = (byte) landData.category; | ||
129 | updatePacket.ParcelData.ClaimDate = landData.claimDate; | ||
130 | updatePacket.ParcelData.ClaimPrice = landData.claimPrice; | ||
131 | updatePacket.ParcelData.GroupID = landData.groupID; | ||
132 | updatePacket.ParcelData.GroupPrims = landData.groupPrims; | ||
133 | updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; | ||
134 | updatePacket.ParcelData.LandingType = (byte) landData.landingType; | ||
135 | updatePacket.ParcelData.LocalID = landData.localID; | ||
136 | if (landData.area > 0) | ||
137 | { | ||
138 | updatePacket.ParcelData.MaxPrims = | ||
139 | Convert.ToInt32( | ||
140 | Math.Round((Convert.ToDecimal(landData.area)/Convert.ToDecimal(65536))*15000* | ||
141 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | updatePacket.ParcelData.MaxPrims = 0; | ||
146 | } | ||
147 | updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; | ||
148 | updatePacket.ParcelData.MediaID = landData.mediaID; | ||
149 | updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); | ||
150 | updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); | ||
151 | updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); | ||
152 | updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented | ||
153 | updatePacket.ParcelData.OtherCount = 0; //unemplemented | ||
154 | updatePacket.ParcelData.OtherPrims = landData.otherPrims; | ||
155 | updatePacket.ParcelData.OwnerID = landData.ownerID; | ||
156 | updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; | ||
157 | updatePacket.ParcelData.ParcelFlags = landData.landFlags; | ||
158 | updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.EstateSettings.objectBonusFactor; | ||
159 | updatePacket.ParcelData.PassHours = landData.passHours; | ||
160 | updatePacket.ParcelData.PassPrice = landData.passPrice; | ||
161 | updatePacket.ParcelData.PublicCount = 0; //unemplemented | ||
162 | |||
163 | uint regionFlags = (uint) m_scene.RegionInfo.EstateSettings.regionFlags; | ||
164 | updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint) Simulator.RegionFlags.DenyAnonymous) > | ||
165 | 0); | ||
166 | updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint) Simulator.RegionFlags.DenyIdentified) > | ||
167 | 0); | ||
168 | updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint) Simulator.RegionFlags.DenyTransacted) > | ||
169 | 0); | ||
170 | updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint) Simulator.RegionFlags.RestrictPushObject) > | ||
171 | 0); | ||
172 | |||
173 | updatePacket.ParcelData.RentPrice = 0; | ||
174 | updatePacket.ParcelData.RequestResult = request_result; | ||
175 | updatePacket.ParcelData.SalePrice = landData.salePrice; | ||
176 | updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; | ||
177 | updatePacket.ParcelData.SelfCount = 0; //unemplemented | ||
178 | updatePacket.ParcelData.SequenceID = sequence_id; | ||
179 | if (landData.simwideArea > 0) | ||
180 | { | ||
181 | updatePacket.ParcelData.SimWideMaxPrims = | ||
182 | Convert.ToInt32( | ||
183 | Math.Round((Convert.ToDecimal(landData.simwideArea)/Convert.ToDecimal(65536))*15000* | ||
184 | Convert.ToDecimal(m_scene.RegionInfo.EstateSettings.objectBonusFactor))); | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | updatePacket.ParcelData.SimWideMaxPrims = 0; | ||
189 | } | ||
190 | updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; | ||
191 | updatePacket.ParcelData.SnapSelection = snap_selection; | ||
192 | updatePacket.ParcelData.SnapshotID = landData.snapshotID; | ||
193 | updatePacket.ParcelData.Status = (byte) landData.landStatus; | ||
194 | updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + | ||
195 | landData.selectedPrims; | ||
196 | updatePacket.ParcelData.UserLocation = landData.userLocation; | ||
197 | updatePacket.ParcelData.UserLookAt = landData.userLookAt; | ||
198 | remote_client.OutPacket((Packet) updatePacket, ThrottleOutPacketType.Task); | ||
199 | } | ||
200 | |||
201 | public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) | ||
202 | { | ||
203 | if (remote_client.AgentId == landData.ownerID) | ||
204 | { | ||
205 | //Needs later group support | ||
206 | LandData newData = landData.Copy(); | ||
207 | newData.authBuyerID = packet.ParcelData.AuthBuyerID; | ||
208 | newData.category = (Parcel.ParcelCategory) packet.ParcelData.Category; | ||
209 | newData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); | ||
210 | newData.groupID = packet.ParcelData.GroupID; | ||
211 | newData.landingType = packet.ParcelData.LandingType; | ||
212 | newData.mediaAutoScale = packet.ParcelData.MediaAutoScale; | ||
213 | newData.mediaID = packet.ParcelData.MediaID; | ||
214 | newData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); | ||
215 | newData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); | ||
216 | newData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); | ||
217 | newData.landFlags = packet.ParcelData.ParcelFlags; | ||
218 | newData.passHours = packet.ParcelData.PassHours; | ||
219 | newData.passPrice = packet.ParcelData.PassPrice; | ||
220 | newData.salePrice = packet.ParcelData.SalePrice; | ||
221 | newData.snapshotID = packet.ParcelData.SnapshotID; | ||
222 | newData.userLocation = packet.ParcelData.UserLocation; | ||
223 | newData.userLookAt = packet.ParcelData.UserLookAt; | ||
224 | |||
225 | m_scene.LandManager.updateLandObject(landData.localID, newData); | ||
226 | |||
227 | sendLandUpdateToAvatarsOverMe(); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | public bool isEitherBannedOrRestricted(LLUUID avatar) | ||
232 | { | ||
233 | if (isBannedFromLand(avatar)) | ||
234 | { | ||
235 | return true; | ||
236 | } | ||
237 | else if (isRestrictedFromLand(avatar)) | ||
238 | { | ||
239 | return true; | ||
240 | } | ||
241 | return false; | ||
242 | } | ||
243 | |||
244 | public bool isBannedFromLand(LLUUID avatar) | ||
245 | { | ||
246 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseBanList) > 0) | ||
247 | { | ||
248 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | ||
249 | entry.AgentID = avatar; | ||
250 | entry.Flags = ParcelManager.AccessList.Ban; | ||
251 | entry.Time = new DateTime(); | ||
252 | if (landData.parcelAccessList.Contains(entry)) | ||
253 | { | ||
254 | //They are banned, so lets send them a notice about this parcel | ||
255 | return true; | ||
256 | } | ||
257 | } | ||
258 | return false; | ||
259 | } | ||
260 | |||
261 | public bool isRestrictedFromLand(LLUUID avatar) | ||
262 | { | ||
263 | if ((landData.landFlags & (uint) Parcel.ParcelFlags.UseAccessList) > 0) | ||
264 | { | ||
265 | ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); | ||
266 | entry.AgentID = avatar; | ||
267 | entry.Flags = ParcelManager.AccessList.Access; | ||
268 | entry.Time = new DateTime(); | ||
269 | if (!landData.parcelAccessList.Contains(entry)) | ||
270 | { | ||
271 | //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel | ||
272 | return true; | ||
273 | } | ||
274 | } | ||
275 | return false; | ||
276 | } | ||
277 | |||
278 | public void sendLandUpdateToClient(IClientAPI remote_client) | ||
279 | { | ||
280 | sendLandProperties(0, false, 0, remote_client); | ||
281 | } | ||
282 | |||
283 | public void sendLandUpdateToAvatarsOverMe() | ||
284 | { | ||
285 | List<ScenePresence> avatars = m_scene.GetAvatars(); | ||
286 | Land over = null; | ||
287 | for (int i = 0; i < avatars.Count; i++) | ||
288 | { | ||
289 | try | ||
290 | { | ||
291 | over = | ||
292 | m_scene.LandManager.getLandObject((int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.X))), | ||
293 | (int)Math.Max(255,Math.Min(0,Math.Round(avatars[i].AbsolutePosition.Y)))); | ||
294 | } | ||
295 | catch (Exception) | ||
296 | { | ||
297 | m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatars[i].AbsolutePosition.X) + " y: " + Math.Round(avatars[i].AbsolutePosition.Y)); | ||
298 | } | ||
299 | |||
300 | if (over != null) | ||
301 | { | ||
302 | if (over.landData.localID == landData.localID) | ||
303 | { | ||
304 | sendLandUpdateToClient(avatars[i].ControllingClient); | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 | #endregion | ||
311 | |||
312 | #region AccessList Functions | ||
313 | |||
314 | public ParcelAccessListReplyPacket.ListBlock[] createAccessListArrayByFlag(ParcelManager.AccessList flag) | ||
315 | { | ||
316 | List<ParcelAccessListReplyPacket.ListBlock> list = new List<ParcelAccessListReplyPacket.ListBlock>(); | ||
317 | foreach (ParcelManager.ParcelAccessEntry entry in landData.parcelAccessList) | ||
318 | { | ||
319 | if (entry.Flags == flag) | ||
320 | { | ||
321 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); | ||
322 | |||
323 | listBlock.Flags = (uint) 0; | ||
324 | listBlock.ID = entry.AgentID; | ||
325 | listBlock.Time = 0; | ||
326 | |||
327 | list.Add(listBlock); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if (list.Count == 0) | ||
332 | { | ||
333 | ParcelAccessListReplyPacket.ListBlock listBlock = new ParcelAccessListReplyPacket.ListBlock(); | ||
334 | |||
335 | listBlock.Flags = (uint) 0; | ||
336 | listBlock.ID = LLUUID.Zero; | ||
337 | listBlock.Time = 0; | ||
338 | |||
339 | list.Add(listBlock); | ||
340 | } | ||
341 | return list.ToArray(); | ||
342 | } | ||
343 | |||
344 | public void sendAccessList(LLUUID agentID, LLUUID sessionID, uint flags, int sequenceID, | ||
345 | IClientAPI remote_client) | ||
346 | { | ||
347 | ParcelAccessListReplyPacket replyPacket; | ||
348 | |||
349 | if (flags == (uint) ParcelManager.AccessList.Access || flags == (uint) ParcelManager.AccessList.Both) | ||
350 | { | ||
351 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); | ||
352 | replyPacket.Data.AgentID = agentID; | ||
353 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Access; | ||
354 | replyPacket.Data.LocalID = landData.localID; | ||
355 | replyPacket.Data.SequenceID = 0; | ||
356 | |||
357 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Access); | ||
358 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); | ||
359 | } | ||
360 | |||
361 | if (flags == (uint) ParcelManager.AccessList.Ban || flags == (uint) ParcelManager.AccessList.Both) | ||
362 | { | ||
363 | replyPacket = (ParcelAccessListReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelAccessListReply); | ||
364 | replyPacket.Data.AgentID = agentID; | ||
365 | replyPacket.Data.Flags = (uint) ParcelManager.AccessList.Ban; | ||
366 | replyPacket.Data.LocalID = landData.localID; | ||
367 | replyPacket.Data.SequenceID = 0; | ||
368 | |||
369 | replyPacket.List = createAccessListArrayByFlag(ParcelManager.AccessList.Ban); | ||
370 | remote_client.OutPacket((Packet) replyPacket, ThrottleOutPacketType.Task); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | public void updateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) | ||
375 | { | ||
376 | LandData newData = landData.Copy(); | ||
377 | |||
378 | if (entries.Count == 1 && entries[0].AgentID == LLUUID.Zero) | ||
379 | { | ||
380 | entries.Clear(); | ||
381 | } | ||
382 | |||
383 | List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); | ||
384 | foreach (ParcelManager.ParcelAccessEntry entry in newData.parcelAccessList) | ||
385 | { | ||
386 | if (entry.Flags == (ParcelManager.AccessList) flags) | ||
387 | { | ||
388 | toRemove.Add(entry); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | foreach (ParcelManager.ParcelAccessEntry entry in toRemove) | ||
393 | { | ||
394 | newData.parcelAccessList.Remove(entry); | ||
395 | } | ||
396 | foreach (ParcelManager.ParcelAccessEntry entry in entries) | ||
397 | { | ||
398 | ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); | ||
399 | temp.AgentID = entry.AgentID; | ||
400 | temp.Time = new DateTime(); //Pointless? Yes. | ||
401 | temp.Flags = (ParcelManager.AccessList) flags; | ||
402 | |||
403 | if (!newData.parcelAccessList.Contains(temp)) | ||
404 | { | ||
405 | newData.parcelAccessList.Add(temp); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | m_scene.LandManager.updateLandObject(landData.localID, newData); | ||
410 | } | ||
411 | |||
412 | #endregion | ||
413 | |||
414 | #region Update Functions | ||
415 | |||
416 | /// <summary> | ||
417 | /// Updates the AABBMin and AABBMax values after area/shape modification of the land object | ||
418 | /// </summary> | ||
419 | private void updateAABBAndAreaValues() | ||
420 | { | ||
421 | int min_x = 64; | ||
422 | int min_y = 64; | ||
423 | int max_x = 0; | ||
424 | int max_y = 0; | ||
425 | int tempArea = 0; | ||
426 | int x, y; | ||
427 | for (x = 0; x < 64; x++) | ||
428 | { | ||
429 | for (y = 0; y < 64; y++) | ||
430 | { | ||
431 | if (landBitmap[x, y] == true) | ||
432 | { | ||
433 | if (min_x > x) min_x = x; | ||
434 | if (min_y > y) min_y = y; | ||
435 | if (max_x < x) max_x = x; | ||
436 | if (max_y < y) max_y = y; | ||
437 | tempArea += 16; //16sqm peice of land | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | int tx = min_x * 4; | ||
442 | if (tx > 255) | ||
443 | tx = 255; | ||
444 | int ty = min_y * 4; | ||
445 | if (ty > 255) | ||
446 | ty = 255; | ||
447 | landData.AABBMin = | ||
448 | new LLVector3((float)(min_x * 4), (float)(min_y * 4), | ||
449 | (float)m_scene.Heightmap[tx, ty]); | ||
450 | |||
451 | tx = max_x * 4; | ||
452 | if (tx > 255) | ||
453 | tx = 255; | ||
454 | ty = max_y * 4; | ||
455 | if (ty > 255) | ||
456 | ty = 255; | ||
457 | landData.AABBMax = | ||
458 | new LLVector3((float)(max_x * 4), (float)(max_y * 4), | ||
459 | (float)m_scene.Heightmap[tx, ty]); | ||
460 | landData.area = tempArea; | ||
461 | } | ||
462 | |||
463 | public void updateLandBitmapByteArray() | ||
464 | { | ||
465 | landData.landBitmapByteArray = convertLandBitmapToBytes(); | ||
466 | } | ||
467 | |||
468 | /// <summary> | ||
469 | /// Update all settings in land such as area, bitmap byte array, etc | ||
470 | /// </summary> | ||
471 | public void forceUpdateLandInfo() | ||
472 | { | ||
473 | updateAABBAndAreaValues(); | ||
474 | updateLandBitmapByteArray(); | ||
475 | } | ||
476 | |||
477 | public void setLandBitmapFromByteArray() | ||
478 | { | ||
479 | landBitmap = convertBytesToLandBitmap(); | ||
480 | } | ||
481 | |||
482 | #endregion | ||
483 | |||
484 | #region Land Bitmap Functions | ||
485 | |||
486 | /// <summary> | ||
487 | /// Sets the land's bitmap manually | ||
488 | /// </summary> | ||
489 | /// <param name="bitmap">64x64 block representing where this land is on a map</param> | ||
490 | public void setLandBitmap(bool[,] bitmap) | ||
491 | { | ||
492 | if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) | ||
493 | { | ||
494 | //Throw an exception - The bitmap is not 64x64 | ||
495 | //throw new Exception("Error: Invalid Parcel Bitmap"); | ||
496 | } | ||
497 | else | ||
498 | { | ||
499 | //Valid: Lets set it | ||
500 | landBitmap = bitmap; | ||
501 | forceUpdateLandInfo(); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | /// <summary> | ||
506 | /// Gets the land's bitmap manually | ||
507 | /// </summary> | ||
508 | /// <returns></returns> | ||
509 | public bool[,] getLandBitmap() | ||
510 | { | ||
511 | return landBitmap; | ||
512 | } | ||
513 | |||
514 | /// <summary> | ||
515 | /// Converts the land bitmap to a packet friendly byte array | ||
516 | /// </summary> | ||
517 | /// <returns></returns> | ||
518 | private byte[] convertLandBitmapToBytes() | ||
519 | { | ||
520 | byte[] tempConvertArr = new byte[512]; | ||
521 | byte tempByte = 0; | ||
522 | int x, y, i, byteNum = 0; | ||
523 | i = 0; | ||
524 | for (y = 0; y < 64; y++) | ||
525 | { | ||
526 | for (x = 0; x < 64; x++) | ||
527 | { | ||
528 | tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++%8)); | ||
529 | if (i%8 == 0) | ||
530 | { | ||
531 | tempConvertArr[byteNum] = tempByte; | ||
532 | tempByte = (byte) 0; | ||
533 | i = 0; | ||
534 | byteNum++; | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | return tempConvertArr; | ||
539 | } | ||
540 | |||
541 | private bool[,] convertBytesToLandBitmap() | ||
542 | { | ||
543 | bool[,] tempConvertMap = new bool[64,64]; | ||
544 | tempConvertMap.Initialize(); | ||
545 | byte tempByte = 0; | ||
546 | int x = 0, y = 0, i = 0, bitNum = 0; | ||
547 | for (i = 0; i < 512; i++) | ||
548 | { | ||
549 | tempByte = landData.landBitmapByteArray[i]; | ||
550 | for (bitNum = 0; bitNum < 8; bitNum++) | ||
551 | { | ||
552 | bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); | ||
553 | tempConvertMap[x, y] = bit; | ||
554 | x++; | ||
555 | if (x > 63) | ||
556 | { | ||
557 | x = 0; | ||
558 | y++; | ||
559 | } | ||
560 | } | ||
561 | } | ||
562 | return tempConvertMap; | ||
563 | } | ||
564 | |||
565 | /// <summary> | ||
566 | /// Full sim land object creation | ||
567 | /// </summary> | ||
568 | /// <returns></returns> | ||
569 | public static bool[,] basicFullRegionLandBitmap() | ||
570 | { | ||
571 | return getSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize); | ||
572 | } | ||
573 | |||
574 | /// <summary> | ||
575 | /// Used to modify the bitmap between the x and y points. Points use 64 scale | ||
576 | /// </summary> | ||
577 | /// <param name="start_x"></param> | ||
578 | /// <param name="start_y"></param> | ||
579 | /// <param name="end_x"></param> | ||
580 | /// <param name="end_y"></param> | ||
581 | /// <returns></returns> | ||
582 | public static bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) | ||
583 | { | ||
584 | bool[,] tempBitmap = new bool[64,64]; | ||
585 | tempBitmap.Initialize(); | ||
586 | |||
587 | tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); | ||
588 | return tempBitmap; | ||
589 | } | ||
590 | |||
591 | /// <summary> | ||
592 | /// Change a land bitmap at within a square and set those points to a specific value | ||
593 | /// </summary> | ||
594 | /// <param name="land_bitmap"></param> | ||
595 | /// <param name="start_x"></param> | ||
596 | /// <param name="start_y"></param> | ||
597 | /// <param name="end_x"></param> | ||
598 | /// <param name="end_y"></param> | ||
599 | /// <param name="set_value"></param> | ||
600 | /// <returns></returns> | ||
601 | public static bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, | ||
602 | bool set_value) | ||
603 | { | ||
604 | if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) | ||
605 | { | ||
606 | //Throw an exception - The bitmap is not 64x64 | ||
607 | //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); | ||
608 | } | ||
609 | |||
610 | int x, y; | ||
611 | for (y = 0; y < 64; y++) | ||
612 | { | ||
613 | for (x = 0; x < 64; x++) | ||
614 | { | ||
615 | if (x >= start_x/4 && x < end_x/4 | ||
616 | && y >= start_y/4 && y < end_y/4) | ||
617 | { | ||
618 | land_bitmap[x, y] = set_value; | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | return land_bitmap; | ||
623 | } | ||
624 | |||
625 | /// <summary> | ||
626 | /// Join the true values of 2 bitmaps together | ||
627 | /// </summary> | ||
628 | /// <param name="bitmap_base"></param> | ||
629 | /// <param name="bitmap_add"></param> | ||
630 | /// <returns></returns> | ||
631 | public static bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) | ||
632 | { | ||
633 | if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) | ||
634 | { | ||
635 | //Throw an exception - The bitmap is not 64x64 | ||
636 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); | ||
637 | } | ||
638 | if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) | ||
639 | { | ||
640 | //Throw an exception - The bitmap is not 64x64 | ||
641 | throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); | ||
642 | } | ||
643 | |||
644 | int x, y; | ||
645 | for (y = 0; y < 64; y++) | ||
646 | { | ||
647 | for (x = 0; x < 64; x++) | ||
648 | { | ||
649 | if (bitmap_add[x, y]) | ||
650 | { | ||
651 | bitmap_base[x, y] = true; | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | return bitmap_base; | ||
656 | } | ||
657 | |||
658 | #endregion | ||
659 | |||
660 | #region Object Select and Object Owner Listing | ||
661 | |||
662 | public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) | ||
663 | { | ||
664 | List<uint> resultLocalIDs = new List<uint>(); | ||
665 | foreach (SceneObjectGroup obj in primsOverMe) | ||
666 | { | ||
667 | if (obj.LocalId > 0) | ||
668 | { | ||
669 | if (request_type == LandManager.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == landData.ownerID) | ||
670 | { | ||
671 | resultLocalIDs.Add(obj.LocalId); | ||
672 | } | ||
673 | // else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && ...) // TODO: group support | ||
674 | // { | ||
675 | // } | ||
676 | else if (request_type == LandManager.LAND_SELECT_OBJECTS_OTHER && | ||
677 | obj.OwnerID != remote_client.AgentId) | ||
678 | { | ||
679 | resultLocalIDs.Add(obj.LocalId); | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | |||
684 | |||
685 | bool firstCall = true; | ||
686 | int MAX_OBJECTS_PER_PACKET = 251; | ||
687 | ForceObjectSelectPacket pack = (ForceObjectSelectPacket) PacketPool.Instance.GetPacket(PacketType.ForceObjectSelect); | ||
688 | // TODO: don't create new blocks if recycling an old packet | ||
689 | ForceObjectSelectPacket.DataBlock[] data; | ||
690 | while (resultLocalIDs.Count > 0) | ||
691 | { | ||
692 | if (firstCall) | ||
693 | { | ||
694 | pack._Header.ResetList = true; | ||
695 | firstCall = false; | ||
696 | } | ||
697 | else | ||
698 | { | ||
699 | pack._Header.ResetList = false; | ||
700 | } | ||
701 | |||
702 | if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) | ||
703 | { | ||
704 | data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; | ||
705 | } | ||
706 | else | ||
707 | { | ||
708 | data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; | ||
709 | } | ||
710 | |||
711 | int i; | ||
712 | for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) | ||
713 | { | ||
714 | data[i] = new ForceObjectSelectPacket.DataBlock(); | ||
715 | data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); | ||
716 | resultLocalIDs.RemoveAt(0); | ||
717 | } | ||
718 | pack.Data = data; | ||
719 | remote_client.OutPacket((Packet) pack, ThrottleOutPacketType.Task); | ||
720 | } | ||
721 | } | ||
722 | |||
723 | public void sendLandObjectOwners(IClientAPI remote_client) | ||
724 | { | ||
725 | Dictionary<LLUUID, int> ownersAndCount = new Dictionary<LLUUID, int>(); | ||
726 | ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket) PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); | ||
727 | // TODO: don't create new blocks if recycling an old packet | ||
728 | |||
729 | foreach (SceneObjectGroup obj in primsOverMe) | ||
730 | { | ||
731 | if (!ownersAndCount.ContainsKey(obj.OwnerID)) | ||
732 | { | ||
733 | ownersAndCount.Add(obj.OwnerID, 0); | ||
734 | } | ||
735 | ownersAndCount[obj.OwnerID] += obj.PrimCount; | ||
736 | } | ||
737 | if (ownersAndCount.Count > 0) | ||
738 | { | ||
739 | ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32]; | ||
740 | |||
741 | if (ownersAndCount.Count < 32) | ||
742 | { | ||
743 | dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count]; | ||
744 | } | ||
745 | |||
746 | |||
747 | int num = 0; | ||
748 | foreach (LLUUID owner in ownersAndCount.Keys) | ||
749 | { | ||
750 | dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); | ||
751 | dataBlock[num].Count = ownersAndCount[owner]; | ||
752 | dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added | ||
753 | dataBlock[num].OnlineStatus = true; //TODO: fix me later | ||
754 | dataBlock[num].OwnerID = owner; | ||
755 | |||
756 | num++; | ||
757 | } | ||
758 | pack.Data = dataBlock; | ||
759 | } | ||
760 | remote_client.OutPacket(pack, ThrottleOutPacketType.Task); | ||
761 | } | ||
762 | |||
763 | #endregion | ||
764 | |||
765 | #region Object Returning | ||
766 | |||
767 | public void returnObject(SceneObjectGroup obj) | ||
768 | { | ||
769 | } | ||
770 | |||
771 | public void returnLandObjects(int type, LLUUID owner) | ||
772 | { | ||
773 | } | ||
774 | |||
775 | #endregion | ||
776 | |||
777 | #region Object Adding/Removing from Parcel | ||
778 | |||
779 | public void resetLandPrimCounts() | ||
780 | { | ||
781 | landData.groupPrims = 0; | ||
782 | landData.ownerPrims = 0; | ||
783 | landData.otherPrims = 0; | ||
784 | landData.selectedPrims = 0; | ||
785 | primsOverMe.Clear(); | ||
786 | } | ||
787 | |||
788 | public void addPrimToCount(SceneObjectGroup obj) | ||
789 | { | ||
790 | LLUUID prim_owner = obj.OwnerID; | ||
791 | int prim_count = obj.PrimCount; | ||
792 | |||
793 | if (obj.IsSelected) | ||
794 | { | ||
795 | landData.selectedPrims += prim_count; | ||
796 | } | ||
797 | else | ||
798 | { | ||
799 | if (prim_owner == landData.ownerID) | ||
800 | { | ||
801 | landData.ownerPrims += prim_count; | ||
802 | } | ||
803 | else | ||
804 | { | ||
805 | landData.otherPrims += prim_count; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | primsOverMe.Add(obj); | ||
810 | } | ||
811 | |||
812 | public void removePrimFromCount(SceneObjectGroup obj) | ||
813 | { | ||
814 | if (primsOverMe.Contains(obj)) | ||
815 | { | ||
816 | LLUUID prim_owner = obj.OwnerID; | ||
817 | int prim_count = obj.PrimCount; | ||
818 | |||
819 | if (prim_owner == landData.ownerID) | ||
820 | { | ||
821 | landData.ownerPrims -= prim_count; | ||
822 | } | ||
823 | else if (prim_owner == landData.groupID) | ||
824 | { | ||
825 | landData.groupPrims -= prim_count; | ||
826 | } | ||
827 | else | ||
828 | { | ||
829 | landData.otherPrims -= prim_count; | ||
830 | } | ||
831 | |||
832 | primsOverMe.Remove(obj); | ||
833 | } | ||
834 | } | ||
835 | |||
836 | #endregion | ||
837 | |||
838 | #endregion | ||
839 | } | ||
840 | |||
841 | #endregion | ||
842 | } | ||