aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie Thielker2010-08-08 17:53:25 +0200
committerMelanie Thielker2010-08-08 17:53:25 +0200
commit6cb50c49b5ee7840a1b88d1c059742e112bef480 (patch)
tree56fec9fa87b4deea9221015fb553d9b8c70804df /OpenSim/Region
parentThank you, Marck00, for a patch that implemented region distance sorting (diff)
parentThe real fix for unscripted sit positions. This one doesn't fuck everything e... (diff)
downloadopensim-SC-6cb50c49b5ee7840a1b88d1c059742e112bef480.zip
opensim-SC-6cb50c49b5ee7840a1b88d1c059742e112bef480.tar.gz
opensim-SC-6cb50c49b5ee7840a1b88d1c059742e112bef480.tar.bz2
opensim-SC-6cb50c49b5ee7840a1b88d1c059742e112bef480.tar.xz
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs2058
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs13
2 files changed, 1051 insertions, 1020 deletions
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 6864629..fcd993c 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -1,1013 +1,1045 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36 36
37namespace OpenSim.Region.CoreModules.World.Land 37namespace OpenSim.Region.CoreModules.World.Land
38{ 38{
39 /// <summary> 39 /// <summary>
40 /// Keeps track of a specific piece of land's information 40 /// Keeps track of a specific piece of land's information
41 /// </summary> 41 /// </summary>
42 public class LandObject : ILandObject 42 public class LandObject : ILandObject
43 { 43 {
44 #region Member Variables 44 #region Member Variables
45 45
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 #pragma warning disable 0429 47 #pragma warning disable 0429
48 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; 48 private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64;
49 #pragma warning restore 0429 49 #pragma warning restore 0429
50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
51 51
52 private int m_lastSeqId = 0; 52 private int m_lastSeqId = 0;
53 53
54 protected LandData m_landData = new LandData(); 54 protected LandData m_landData = new LandData();
55 protected Scene m_scene; 55 protected Scene m_scene;
56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
57 57
58 public bool[,] LandBitmap 58 public bool[,] LandBitmap
59 { 59 {
60 get { return m_landBitmap; } 60 get { return m_landBitmap; }
61 set { m_landBitmap = value; } 61 set { m_landBitmap = value; }
62 } 62 }
63 63
64 #endregion 64 #endregion
65 65
66 #region ILandObject Members 66 #region ILandObject Members
67 67
68 public LandData LandData 68 public LandData LandData
69 { 69 {
70 get { return m_landData; } 70 get { return m_landData; }
71 71
72 set { m_landData = value; } 72 set { m_landData = value; }
73 } 73 }
74 74
75 public UUID RegionUUID 75 public UUID RegionUUID
76 { 76 {
77 get { return m_scene.RegionInfo.RegionID; } 77 get { return m_scene.RegionInfo.RegionID; }
78 } 78 }
79 79
80 #region Constructors 80 #region Constructors
81 81
82 public LandObject(UUID owner_id, bool is_group_owned, Scene scene) 82 public LandObject(UUID owner_id, bool is_group_owned, Scene scene)
83 { 83 {
84 m_scene = scene; 84 m_scene = scene;
85 LandData.OwnerID = owner_id; 85 LandData.OwnerID = owner_id;
86 if (is_group_owned) 86 if (is_group_owned)
87 LandData.GroupID = owner_id; 87 LandData.GroupID = owner_id;
88 else 88 else
89 LandData.GroupID = UUID.Zero; 89 LandData.GroupID = UUID.Zero;
90 LandData.IsGroupOwned = is_group_owned; 90 LandData.IsGroupOwned = is_group_owned;
91 } 91 }
92 92
93 #endregion 93 #endregion
94 94
95 #region Member Functions 95 #region Member Functions
96 96
97 #region General Functions 97 #region General Functions
98 98
99 /// <summary> 99 /// <summary>
100 /// Checks to see if this land object contains a point 100 /// Checks to see if this land object contains a point
101 /// </summary> 101 /// </summary>
102 /// <param name="x"></param> 102 /// <param name="x"></param>
103 /// <param name="y"></param> 103 /// <param name="y"></param>
104 /// <returns>Returns true if the piece of land contains the specified point</returns> 104 /// <returns>Returns true if the piece of land contains the specified point</returns>
105 public bool ContainsPoint(int x, int y) 105 public bool ContainsPoint(int x, int y)
106 { 106 {
107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) 107 if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize)
108 { 108 {
109 return (LandBitmap[x / 4, y / 4] == true); 109 return (LandBitmap[x / 4, y / 4] == true);
110 } 110 }
111 else 111 else
112 { 112 {
113 return false; 113 return false;
114 } 114 }
115 } 115 }
116 116
117 public ILandObject Copy() 117 public ILandObject Copy()
118 { 118 {
119 ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); 119 ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene);
120 120
121 //Place all new variables here! 121 //Place all new variables here!
122 newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); 122 newLand.LandBitmap = (bool[,]) (LandBitmap.Clone());
123 newLand.LandData = LandData.Copy(); 123 newLand.LandData = LandData.Copy();
124 124
125 return newLand; 125 return newLand;
126 } 126 }
127 127
128 static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; 128 static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount;
129 static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; 129 static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount;
130 130
131 public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) 131 public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
132 { 132 {
133 overrideParcelMaxPrimCount = overrideDel; 133 overrideParcelMaxPrimCount = overrideDel;
134 } 134 }
135 public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) 135 public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel)
136 { 136 {
137 overrideSimulatorMaxPrimCount = overrideDel; 137 overrideSimulatorMaxPrimCount = overrideDel;
138 } 138 }
139 139
140 public int GetParcelMaxPrimCount(ILandObject thisObject) 140 public int GetParcelMaxPrimCount(ILandObject thisObject)
141 { 141 {
142 if (overrideParcelMaxPrimCount != null) 142 if (overrideParcelMaxPrimCount != null)
143 { 143 {
144 return overrideParcelMaxPrimCount(thisObject); 144 return overrideParcelMaxPrimCount(thisObject);
145 } 145 }
146 else 146 else
147 { 147 {
148 // Normal Calculations 148 // Normal Calculations
149 return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 149 return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
150 } 150 }
151 } 151 }
152 public int GetSimulatorMaxPrimCount(ILandObject thisObject) 152 public int GetSimulatorMaxPrimCount(ILandObject thisObject)
153 { 153 {
154 if (overrideSimulatorMaxPrimCount != null) 154 if (overrideSimulatorMaxPrimCount != null)
155 { 155 {
156 return overrideSimulatorMaxPrimCount(thisObject); 156 return overrideSimulatorMaxPrimCount(thisObject);
157 } 157 }
158 else 158 else
159 { 159 {
160 //Normal Calculations 160 //Normal Calculations
161 return m_scene.RegionInfo.ObjectCapacity; 161 return m_scene.RegionInfo.ObjectCapacity;
162 } 162 }
163 } 163 }
164 #endregion 164 #endregion
165 165
166 #region Packet Request Handling 166 #region Packet Request Handling
167 167
168 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) 168 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client)
169 { 169 {
170 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 170 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>();
171 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); 171 uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome));
172 if (estateModule != null) 172 if (estateModule != null)
173 regionFlags = estateModule.GetRegionFlags(); 173 regionFlags = estateModule.GetRegionFlags();
174 174
175 // In a perfect world, this would have worked. 175 // In a perfect world, this would have worked.
176 // 176 //
177// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) 177// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0)
178// regionFlags |= (uint)RegionFlags.AllowLandmark; 178// regionFlags |= (uint)RegionFlags.AllowLandmark;
179// if (landData.OwnerID == remote_client.AgentId) 179// if (landData.OwnerID == remote_client.AgentId)
180// regionFlags |= (uint)RegionFlags.AllowSetHome; 180// regionFlags |= (uint)RegionFlags.AllowSetHome;
181 181
182 int seq_id; 182 int seq_id;
183 if (snap_selection && (sequence_id == 0)) 183 if (snap_selection && (sequence_id == 0))
184 { 184 {
185 seq_id = m_lastSeqId; 185 seq_id = m_lastSeqId;
186 } 186 }
187 else 187 else
188 { 188 {
189 seq_id = sequence_id; 189 seq_id = sequence_id;
190 m_lastSeqId = seq_id; 190 m_lastSeqId = seq_id;
191 } 191 }
192 192
193 remote_client.SendLandProperties(seq_id, 193 remote_client.SendLandProperties(seq_id,
194 snap_selection, request_result, LandData, 194 snap_selection, request_result, LandData,
195 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 195 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
196 GetParcelMaxPrimCount(this), 196 GetParcelMaxPrimCount(this),
197 GetSimulatorMaxPrimCount(this), regionFlags); 197 GetSimulatorMaxPrimCount(this), regionFlags);
198 } 198 }
199 199
200 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) 200 public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client)
201 { 201 {
202 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) 202 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this))
203 { 203 {
204 //Needs later group support 204 //Needs later group support
205 bool snap_selection = false; 205 bool snap_selection = false;
206 LandData newData = LandData.Copy(); 206 LandData newData = LandData.Copy();
207 207
208 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) 208 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice)
209 { 209 {
210 if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) 210 if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this))
211 { 211 {
212 newData.AuthBuyerID = args.AuthBuyerID; 212 newData.AuthBuyerID = args.AuthBuyerID;
213 newData.SalePrice = args.SalePrice; 213 newData.SalePrice = args.SalePrice;
214 snap_selection = true; 214 snap_selection = true;
215 } 215 }
216 } 216 }
217 newData.Category = args.Category; 217 newData.Category = args.Category;
218 newData.Description = args.Desc; 218 newData.Description = args.Desc;
219 newData.GroupID = args.GroupID; 219 newData.GroupID = args.GroupID;
220 newData.LandingType = args.LandingType; 220 newData.LandingType = args.LandingType;
221 newData.MediaAutoScale = args.MediaAutoScale; 221 newData.MediaAutoScale = args.MediaAutoScale;
222 newData.MediaID = args.MediaID; 222 newData.MediaID = args.MediaID;
223 newData.MediaURL = args.MediaURL; 223 newData.MediaURL = args.MediaURL;
224 newData.MusicURL = args.MusicURL; 224 newData.MusicURL = args.MusicURL;
225 newData.Name = args.Name; 225 newData.Name = args.Name;
226 newData.Flags = args.ParcelFlags; 226 newData.Flags = args.ParcelFlags;
227 newData.PassHours = args.PassHours; 227 newData.PassHours = args.PassHours;
228 newData.PassPrice = args.PassPrice; 228 newData.PassPrice = args.PassPrice;
229 newData.SnapshotID = args.SnapshotID; 229 newData.SnapshotID = args.SnapshotID;
230 newData.UserLocation = args.UserLocation; 230 newData.UserLocation = args.UserLocation;
231 newData.UserLookAt = args.UserLookAt; 231 newData.UserLookAt = args.UserLookAt;
232 232
233 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 233 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
234 234
235 SendLandUpdateToAvatarsOverMe(snap_selection); 235 SendLandUpdateToAvatarsOverMe(snap_selection);
236 } 236 }
237 } 237 }
238 238
239 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) 239 public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area)
240 { 240 {
241 LandData newData = LandData.Copy(); 241 LandData newData = LandData.Copy();
242 newData.OwnerID = avatarID; 242 newData.OwnerID = avatarID;
243 newData.GroupID = groupID; 243 newData.GroupID = groupID;
244 newData.IsGroupOwned = groupOwned; 244 newData.IsGroupOwned = groupOwned;
245 //newData.auctionID = AuctionID; 245 //newData.auctionID = AuctionID;
246 newData.ClaimDate = Util.UnixTimeSinceEpoch(); 246 newData.ClaimDate = Util.UnixTimeSinceEpoch();
247 newData.ClaimPrice = claimprice; 247 newData.ClaimPrice = claimprice;
248 newData.SalePrice = 0; 248 newData.SalePrice = 0;
249 newData.AuthBuyerID = UUID.Zero; 249 newData.AuthBuyerID = UUID.Zero;
250 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 250 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
251 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 251 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
252 252
253 SendLandUpdateToAvatarsOverMe(true); 253 SendLandUpdateToAvatarsOverMe(true);
254 } 254 }
255 255
256 public void DeedToGroup(UUID groupID) 256 public void DeedToGroup(UUID groupID)
257 { 257 {
258 LandData newData = LandData.Copy(); 258 LandData newData = LandData.Copy();
259 newData.OwnerID = groupID; 259 newData.OwnerID = groupID;
260 newData.GroupID = groupID; 260 newData.GroupID = groupID;
261 newData.IsGroupOwned = true; 261 newData.IsGroupOwned = true;
262 262
263 // Reset show in directory flag on deed 263 // Reset show in directory flag on deed
264 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); 264 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory);
265 265
266 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 266 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
267 267
268 SendLandUpdateToAvatarsOverMe(true); 268 SendLandUpdateToAvatarsOverMe(true);
269 } 269 }
270 270
271 public bool IsEitherBannedOrRestricted(UUID avatar) 271 public bool IsEitherBannedOrRestricted(UUID avatar)
272 { 272 {
273 if (IsBannedFromLand(avatar)) 273 if (IsBannedFromLand(avatar))
274 { 274 {
275 return true; 275 return true;
276 } 276 }
277 else if (IsRestrictedFromLand(avatar)) 277 else if (IsRestrictedFromLand(avatar))
278 { 278 {
279 return true; 279 return true;
280 } 280 }
281 return false; 281 return false;
282 } 282 }
283 283
284 public bool IsBannedFromLand(UUID avatar) 284 public bool HasGroupAccess(UUID avatar)
285 { 285 {
286 if (m_scene.Permissions.IsAdministrator(avatar)) 286 if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
287 return false; 287 {
288 288 IGroupsModule groupsModule =
289 if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) 289 m_scene.RequestModuleInterface<IGroupsModule>();
290 { 290
291 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 291 List<UUID> agentGroups = new List<UUID>();
292 entry.AgentID = avatar; 292 if (groupsModule != null)
293 entry.Flags = AccessList.Ban; 293 {
294 entry.Time = new DateTime(); 294 GroupMembershipData[] GroupMembership =
295 //See if they are on the list, but make sure the owner isn't banned 295 groupsModule.GetMembershipData(avatar);
296 if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) 296
297 { 297 if (GroupMembership != null)
298 //They are banned, so lets send them a notice about this parcel 298 {
299 return true; 299 for (int i = 0; i < GroupMembership.Length; i++)
300 } 300 {
301 } 301 if (LandData.GroupID == GroupMembership[i].GroupID)
302 return false; 302 {
303 } 303 return true;
304 304 }
305 public bool IsRestrictedFromLand(UUID avatar) 305 }
306 { 306 }
307 if (m_scene.Permissions.IsAdministrator(avatar)) 307 }
308 return false; 308 }
309 309 return false;
310 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) 310 }
311 { 311
312 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 312 public bool IsBannedFromLand(UUID avatar)
313 entry.AgentID = avatar; 313 {
314 entry.Flags = AccessList.Access; 314 if (m_scene.Permissions.IsAdministrator(avatar))
315 entry.Time = new DateTime(); 315 return false;
316 316
317 //If they are not on the access list and are not the owner 317 if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0)
318 if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) 318 {
319 { 319 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
320 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel 320 entry.AgentID = avatar;
321 return true; 321 entry.Flags = AccessList.Ban;
322 } 322 entry.Time = new DateTime();
323 } 323 //See if they are on the list, but make sure the owner isn't banned
324 return false; 324 if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar)
325 } 325 {
326 326 //They are banned, so lets send them a notice about this parcel
327 public void SendLandUpdateToClient(IClientAPI remote_client) 327 return true;
328 { 328 }
329 SendLandProperties(0, false, 0, remote_client); 329 }
330 } 330 return false;
331 331 }
332 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) 332
333 { 333 public bool IsRestrictedFromLand(UUID avatar)
334 SendLandProperties(0, snap_selection, 0, remote_client); 334 {
335 } 335 if (m_scene.Permissions.IsAdministrator(avatar))
336 336 return false;
337 public void SendLandUpdateToAvatarsOverMe() 337
338 { 338 if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0)
339 SendLandUpdateToAvatarsOverMe(false); 339 {
340 } 340 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
341 341 entry.AgentID = avatar;
342 public void SendLandUpdateToAvatarsOverMe(bool snap_selection) 342 entry.Flags = AccessList.Access;
343 { 343 entry.Time = new DateTime();
344 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 344
345 { 345 //If they are not on the access list and are not the owner
346 if (avatar.IsChildAgent) 346 if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar)
347 return; 347 {
348 348 if (!HasGroupAccess(avatar))
349 ILandObject over = null; 349 {
350 try 350 //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel
351 { 351 return true;
352 over = 352 }
353 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), 353 }
354 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); 354 }
355 } 355
356 catch (Exception) 356 return false;
357 { 357 }
358 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + 358
359 Math.Round(avatar.AbsolutePosition.Y)); 359 public void SendLandUpdateToClient(IClientAPI remote_client)
360 } 360 {
361 361 SendLandProperties(0, false, 0, remote_client);
362 if (over != null) 362 }
363 { 363
364 if (over.LandData.LocalID == LandData.LocalID) 364 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
365 { 365 {
366 if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && 366 SendLandProperties(0, snap_selection, 0, remote_client);
367 m_scene.RegionInfo.RegionSettings.AllowDamage) 367 }
368 avatar.Invulnerable = false; 368
369 else 369 public void SendLandUpdateToAvatarsOverMe()
370 avatar.Invulnerable = true; 370 {
371 371 SendLandUpdateToAvatarsOverMe(false);
372 SendLandUpdateToClient(snap_selection, avatar.ControllingClient); 372 }
373 } 373
374 } 374 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
375 }); 375 {
376 } 376 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
377 377 {
378 #endregion 378 if (avatar.IsChildAgent)
379 379 return;
380 #region AccessList Functions 380
381 381 ILandObject over = null;
382 public List<UUID> CreateAccessListArrayByFlag(AccessList flag) 382 try
383 { 383 {
384 List<UUID> list = new List<UUID>(); 384 over =
385 foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) 385 m_scene.LandChannel.GetLandObject(Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)),
386 { 386 Util.Clamp<int>((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1)));
387 if (entry.Flags == flag) 387 }
388 { 388 catch (Exception)
389 list.Add(entry.AgentID); 389 {
390 } 390 m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " +
391 } 391 Math.Round(avatar.AbsolutePosition.Y));
392 if (list.Count == 0) 392 }
393 { 393
394 list.Add(UUID.Zero); 394 if (over != null)
395 } 395 {
396 396 if (over.LandData.LocalID == LandData.LocalID)
397 return list; 397 {
398 } 398 if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) &&
399 399 m_scene.RegionInfo.RegionSettings.AllowDamage)
400 public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, 400 avatar.Invulnerable = false;
401 IClientAPI remote_client) 401 else
402 { 402 avatar.Invulnerable = true;
403 403
404 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) 404 SendLandUpdateToClient(snap_selection, avatar.ControllingClient);
405 { 405 }
406 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Access); 406 }
407 remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); 407 });
408 } 408 }
409 409
410 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) 410 #endregion
411 { 411
412 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Ban); 412 #region AccessList Functions
413 remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); 413
414 } 414 public List<UUID> CreateAccessListArrayByFlag(AccessList flag)
415 } 415 {
416 416 List<UUID> list = new List<UUID>();
417 public void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client) 417 foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList)
418 { 418 {
419 LandData newData = LandData.Copy(); 419 if (entry.Flags == flag)
420 420 {
421 if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) 421 list.Add(entry.AgentID);
422 { 422 }
423 entries.Clear(); 423 }
424 } 424 if (list.Count == 0)
425 425 {
426 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>(); 426 list.Add(UUID.Zero);
427 foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) 427 }
428 { 428
429 if (entry.Flags == (AccessList)flags) 429 return list;
430 { 430 }
431 toRemove.Add(entry); 431
432 } 432 public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID,
433 } 433 IClientAPI remote_client)
434 434 {
435 foreach (ParcelManager.ParcelAccessEntry entry in toRemove) 435
436 { 436 if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both)
437 newData.ParcelAccessList.Remove(entry); 437 {
438 } 438 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Access);
439 foreach (ParcelManager.ParcelAccessEntry entry in entries) 439 remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID);
440 { 440 }
441 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); 441
442 temp.AgentID = entry.AgentID; 442 if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both)
443 temp.Time = new DateTime(); //Pointless? Yes. 443 {
444 temp.Flags = (AccessList)flags; 444 List<UUID> avatars = CreateAccessListArrayByFlag(AccessList.Ban);
445 445 remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID);
446 if (!newData.ParcelAccessList.Contains(temp)) 446 }
447 { 447 }
448 newData.ParcelAccessList.Add(temp); 448
449 } 449 public void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client)
450 } 450 {
451 451 LandData newData = LandData.Copy();
452 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 452
453 } 453 if (entries.Count == 1 && entries[0].AgentID == UUID.Zero)
454 454 {
455 #endregion 455 entries.Clear();
456 456 }
457 #region Update Functions 457
458 458 List<ParcelManager.ParcelAccessEntry> toRemove = new List<ParcelManager.ParcelAccessEntry>();
459 public void UpdateLandBitmapByteArray() 459 foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList)
460 { 460 {
461 LandData.Bitmap = ConvertLandBitmapToBytes(); 461 if (entry.Flags == (AccessList)flags)
462 } 462 {
463 463 toRemove.Add(entry);
464 /// <summary> 464 }
465 /// Update all settings in land such as area, bitmap byte array, etc 465 }
466 /// </summary> 466
467 public void ForceUpdateLandInfo() 467 foreach (ParcelManager.ParcelAccessEntry entry in toRemove)
468 { 468 {
469 UpdateAABBAndAreaValues(); 469 newData.ParcelAccessList.Remove(entry);
470 UpdateLandBitmapByteArray(); 470 }
471 } 471 foreach (ParcelManager.ParcelAccessEntry entry in entries)
472 472 {
473 public void SetLandBitmapFromByteArray() 473 ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry();
474 { 474 temp.AgentID = entry.AgentID;
475 LandBitmap = ConvertBytesToLandBitmap(); 475 temp.Time = new DateTime(); //Pointless? Yes.
476 } 476 temp.Flags = (AccessList)flags;
477 477
478 /// <summary> 478 if (!newData.ParcelAccessList.Contains(temp))
479 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object 479 {
480 /// </summary> 480 newData.ParcelAccessList.Add(temp);
481 private void UpdateAABBAndAreaValues() 481 }
482 { 482 }
483 int min_x = 64; 483
484 int min_y = 64; 484 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
485 int max_x = 0; 485 }
486 int max_y = 0; 486
487 int tempArea = 0; 487 #endregion
488 int x, y; 488
489 for (x = 0; x < 64; x++) 489 #region Update Functions
490 { 490
491 for (y = 0; y < 64; y++) 491 public void UpdateLandBitmapByteArray()
492 { 492 {
493 if (LandBitmap[x, y] == true) 493 LandData.Bitmap = ConvertLandBitmapToBytes();
494 { 494 }
495 if (min_x > x) min_x = x; 495
496 if (min_y > y) min_y = y; 496 /// <summary>
497 if (max_x < x) max_x = x; 497 /// Update all settings in land such as area, bitmap byte array, etc
498 if (max_y < y) max_y = y; 498 /// </summary>
499 tempArea += 16; //16sqm peice of land 499 public void ForceUpdateLandInfo()
500 } 500 {
501 } 501 UpdateAABBAndAreaValues();
502 } 502 UpdateLandBitmapByteArray();
503 int tx = min_x * 4; 503 }
504 if (tx > ((int)Constants.RegionSize - 1)) 504
505 tx = ((int)Constants.RegionSize - 1); 505 public void SetLandBitmapFromByteArray()
506 int ty = min_y * 4; 506 {
507 if (ty > ((int)Constants.RegionSize - 1)) 507 LandBitmap = ConvertBytesToLandBitmap();
508 ty = ((int)Constants.RegionSize - 1); 508 }
509 LandData.AABBMin = 509
510 new Vector3((float) (min_x * 4), (float) (min_y * 4), 510 /// <summary>
511 (float) m_scene.Heightmap[tx, ty]); 511 /// Updates the AABBMin and AABBMax values after area/shape modification of the land object
512 512 /// </summary>
513 tx = max_x * 4; 513 private void UpdateAABBAndAreaValues()
514 if (tx > ((int)Constants.RegionSize - 1)) 514 {
515 tx = ((int)Constants.RegionSize - 1); 515 int min_x = 64;
516 ty = max_y * 4; 516 int min_y = 64;
517 if (ty > ((int)Constants.RegionSize - 1)) 517 int max_x = 0;
518 ty = ((int)Constants.RegionSize - 1); 518 int max_y = 0;
519 LandData.AABBMax = 519 int tempArea = 0;
520 new Vector3((float) (max_x * 4), (float) (max_y * 4), 520 int x, y;
521 (float) m_scene.Heightmap[tx, ty]); 521 for (x = 0; x < 64; x++)
522 LandData.Area = tempArea; 522 {
523 } 523 for (y = 0; y < 64; y++)
524 524 {
525 #endregion 525 if (LandBitmap[x, y] == true)
526 526 {
527 #region Land Bitmap Functions 527 if (min_x > x) min_x = x;
528 528 if (min_y > y) min_y = y;
529 /// <summary> 529 if (max_x < x) max_x = x;
530 /// Sets the land's bitmap manually 530 if (max_y < y) max_y = y;
531 /// </summary> 531 tempArea += 16; //16sqm peice of land
532 /// <param name="bitmap">64x64 block representing where this land is on a map</param> 532 }
533 public void SetLandBitmap(bool[,] bitmap) 533 }
534 { 534 }
535 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) 535 int tx = min_x * 4;
536 { 536 if (tx > ((int)Constants.RegionSize - 1))
537 //Throw an exception - The bitmap is not 64x64 537 tx = ((int)Constants.RegionSize - 1);
538 //throw new Exception("Error: Invalid Parcel Bitmap"); 538 int ty = min_y * 4;
539 } 539 if (ty > ((int)Constants.RegionSize - 1))
540 else 540 ty = ((int)Constants.RegionSize - 1);
541 { 541 LandData.AABBMin =
542 //Valid: Lets set it 542 new Vector3((float) (min_x * 4), (float) (min_y * 4),
543 LandBitmap = bitmap; 543 (float) m_scene.Heightmap[tx, ty]);
544 ForceUpdateLandInfo(); 544
545 } 545 tx = max_x * 4;
546 } 546 if (tx > ((int)Constants.RegionSize - 1))
547 547 tx = ((int)Constants.RegionSize - 1);
548 /// <summary> 548 ty = max_y * 4;
549 /// Gets the land's bitmap manually 549 if (ty > ((int)Constants.RegionSize - 1))
550 /// </summary> 550 ty = ((int)Constants.RegionSize - 1);
551 /// <returns></returns> 551 LandData.AABBMax =
552 public bool[,] GetLandBitmap() 552 new Vector3((float) (max_x * 4), (float) (max_y * 4),
553 { 553 (float) m_scene.Heightmap[tx, ty]);
554 return LandBitmap; 554 LandData.Area = tempArea;
555 } 555 }
556 556
557 /// <summary> 557 #endregion
558 /// Full sim land object creation 558
559 /// </summary> 559 #region Land Bitmap Functions
560 /// <returns></returns> 560
561 public bool[,] BasicFullRegionLandBitmap() 561 /// <summary>
562 { 562 /// Sets the land's bitmap manually
563 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); 563 /// </summary>
564 } 564 /// <param name="bitmap">64x64 block representing where this land is on a map</param>
565 565 public void SetLandBitmap(bool[,] bitmap)
566 /// <summary> 566 {
567 /// Used to modify the bitmap between the x and y points. Points use 64 scale 567 if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2)
568 /// </summary> 568 {
569 /// <param name="start_x"></param> 569 //Throw an exception - The bitmap is not 64x64
570 /// <param name="start_y"></param> 570 //throw new Exception("Error: Invalid Parcel Bitmap");
571 /// <param name="end_x"></param> 571 }
572 /// <param name="end_y"></param> 572 else
573 /// <returns></returns> 573 {
574 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) 574 //Valid: Lets set it
575 { 575 LandBitmap = bitmap;
576 bool[,] tempBitmap = new bool[64,64]; 576 ForceUpdateLandInfo();
577 tempBitmap.Initialize(); 577 }
578 578 }
579 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); 579
580 return tempBitmap; 580 /// <summary>
581 } 581 /// Gets the land's bitmap manually
582 582 /// </summary>
583 /// <summary> 583 /// <returns></returns>
584 /// Change a land bitmap at within a square and set those points to a specific value 584 public bool[,] GetLandBitmap()
585 /// </summary> 585 {
586 /// <param name="land_bitmap"></param> 586 return LandBitmap;
587 /// <param name="start_x"></param> 587 }
588 /// <param name="start_y"></param> 588
589 /// <param name="end_x"></param> 589 /// <summary>
590 /// <param name="end_y"></param> 590 /// Full sim land object creation
591 /// <param name="set_value"></param> 591 /// </summary>
592 /// <returns></returns> 592 /// <returns></returns>
593 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, 593 public bool[,] BasicFullRegionLandBitmap()
594 bool set_value) 594 {
595 { 595 return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize);
596 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) 596 }
597 { 597
598 //Throw an exception - The bitmap is not 64x64 598 /// <summary>
599 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); 599 /// Used to modify the bitmap between the x and y points. Points use 64 scale
600 } 600 /// </summary>
601 601 /// <param name="start_x"></param>
602 int x, y; 602 /// <param name="start_y"></param>
603 for (y = 0; y < 64; y++) 603 /// <param name="end_x"></param>
604 { 604 /// <param name="end_y"></param>
605 for (x = 0; x < 64; x++) 605 /// <returns></returns>
606 { 606 public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y)
607 if (x >= start_x / 4 && x < end_x / 4 607 {
608 && y >= start_y / 4 && y < end_y / 4) 608 bool[,] tempBitmap = new bool[64,64];
609 { 609 tempBitmap.Initialize();
610 land_bitmap[x, y] = set_value; 610
611 } 611 tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true);
612 } 612 return tempBitmap;
613 } 613 }
614 return land_bitmap; 614
615 } 615 /// <summary>
616 616 /// Change a land bitmap at within a square and set those points to a specific value
617 /// <summary> 617 /// </summary>
618 /// Join the true values of 2 bitmaps together 618 /// <param name="land_bitmap"></param>
619 /// </summary> 619 /// <param name="start_x"></param>
620 /// <param name="bitmap_base"></param> 620 /// <param name="start_y"></param>
621 /// <param name="bitmap_add"></param> 621 /// <param name="end_x"></param>
622 /// <returns></returns> 622 /// <param name="end_y"></param>
623 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) 623 /// <param name="set_value"></param>
624 { 624 /// <returns></returns>
625 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) 625 public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y,
626 { 626 bool set_value)
627 //Throw an exception - The bitmap is not 64x64 627 {
628 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); 628 if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2)
629 } 629 {
630 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) 630 //Throw an exception - The bitmap is not 64x64
631 { 631 //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()");
632 //Throw an exception - The bitmap is not 64x64 632 }
633 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); 633
634 } 634 int x, y;
635 635 for (y = 0; y < 64; y++)
636 int x, y; 636 {
637 for (y = 0; y < 64; y++) 637 for (x = 0; x < 64; x++)
638 { 638 {
639 for (x = 0; x < 64; x++) 639 if (x >= start_x / 4 && x < end_x / 4
640 { 640 && y >= start_y / 4 && y < end_y / 4)
641 if (bitmap_add[x, y]) 641 {
642 { 642 land_bitmap[x, y] = set_value;
643 bitmap_base[x, y] = true; 643 }
644 } 644 }
645 } 645 }
646 } 646 return land_bitmap;
647 return bitmap_base; 647 }
648 } 648
649 649 /// <summary>
650 /// <summary> 650 /// Join the true values of 2 bitmaps together
651 /// Converts the land bitmap to a packet friendly byte array 651 /// </summary>
652 /// </summary> 652 /// <param name="bitmap_base"></param>
653 /// <returns></returns> 653 /// <param name="bitmap_add"></param>
654 private byte[] ConvertLandBitmapToBytes() 654 /// <returns></returns>
655 { 655 public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add)
656 byte[] tempConvertArr = new byte[512]; 656 {
657 byte tempByte = 0; 657 if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2)
658 int x, y, i, byteNum = 0; 658 {
659 i = 0; 659 //Throw an exception - The bitmap is not 64x64
660 for (y = 0; y < 64; y++) 660 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps");
661 { 661 }
662 for (x = 0; x < 64; x++) 662 if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2)
663 { 663 {
664 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); 664 //Throw an exception - The bitmap is not 64x64
665 if (i % 8 == 0) 665 throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps");
666 { 666 }
667 tempConvertArr[byteNum] = tempByte; 667
668 tempByte = (byte) 0; 668 int x, y;
669 i = 0; 669 for (y = 0; y < 64; y++)
670 byteNum++; 670 {
671 } 671 for (x = 0; x < 64; x++)
672 } 672 {
673 } 673 if (bitmap_add[x, y])
674 return tempConvertArr; 674 {
675 } 675 bitmap_base[x, y] = true;
676 676 }
677 private bool[,] ConvertBytesToLandBitmap() 677 }
678 { 678 }
679 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; 679 return bitmap_base;
680 tempConvertMap.Initialize(); 680 }
681 byte tempByte = 0; 681
682 int x = 0, y = 0, i = 0, bitNum = 0; 682 /// <summary>
683 for (i = 0; i < 512; i++) 683 /// Converts the land bitmap to a packet friendly byte array
684 { 684 /// </summary>
685 tempByte = LandData.Bitmap[i]; 685 /// <returns></returns>
686 for (bitNum = 0; bitNum < 8; bitNum++) 686 private byte[] ConvertLandBitmapToBytes()
687 { 687 {
688 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); 688 byte[] tempConvertArr = new byte[512];
689 tempConvertMap[x, y] = bit; 689 byte tempByte = 0;
690 x++; 690 int x, y, i, byteNum = 0;
691 if (x > 63) 691 i = 0;
692 { 692 for (y = 0; y < 64; y++)
693 x = 0; 693 {
694 y++; 694 for (x = 0; x < 64; x++)
695 } 695 {
696 } 696 tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8));
697 } 697 if (i % 8 == 0)
698 return tempConvertMap; 698 {
699 } 699 tempConvertArr[byteNum] = tempByte;
700 700 tempByte = (byte) 0;
701 #endregion 701 i = 0;
702 702 byteNum++;
703 #region Object Select and Object Owner Listing 703 }
704 704 }
705 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client) 705 }
706 { 706 return tempConvertArr;
707 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) 707 }
708 { 708
709 List<uint> resultLocalIDs = new List<uint>(); 709 private bool[,] ConvertBytesToLandBitmap()
710 try 710 {
711 { 711 bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax];
712 lock (primsOverMe) 712 tempConvertMap.Initialize();
713 { 713 byte tempByte = 0;
714 foreach (SceneObjectGroup obj in primsOverMe) 714 int x = 0, y = 0, i = 0, bitNum = 0;
715 { 715 for (i = 0; i < 512; i++)
716 if (obj.LocalId > 0) 716 {
717 { 717 tempByte = LandData.Bitmap[i];
718 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) 718 for (bitNum = 0; bitNum < 8; bitNum++)
719 { 719 {
720 resultLocalIDs.Add(obj.LocalId); 720 bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1);
721 } 721 tempConvertMap[x, y] = bit;
722 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) 722 x++;
723 { 723 if (x > 63)
724 resultLocalIDs.Add(obj.LocalId); 724 {
725 } 725 x = 0;
726 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && 726 y++;
727 obj.OwnerID != remote_client.AgentId) 727 }
728 { 728 }
729 resultLocalIDs.Add(obj.LocalId); 729 }
730 } 730 return tempConvertMap;
731 else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) 731 }
732 { 732
733 resultLocalIDs.Add(obj.LocalId); 733 #endregion
734 } 734
735 } 735 #region Object Select and Object Owner Listing
736 } 736
737 } 737 public void SendForceObjectSelect(int local_id, int request_type, List<UUID> returnIDs, IClientAPI remote_client)
738 } catch (InvalidOperationException) 738 {
739 { 739 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
740 m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); 740 {
741 } 741 List<uint> resultLocalIDs = new List<uint>();
742 742 try
743 remote_client.SendForceClientSelectObjects(resultLocalIDs); 743 {
744 } 744 lock (primsOverMe)
745 } 745 {
746 746 foreach (SceneObjectGroup obj in primsOverMe)
747 /// <summary> 747 {
748 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes 748 if (obj.LocalId > 0)
749 /// aggreagete details such as the number of prims. 749 {
750 /// 750 if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID)
751 /// </summary> 751 {
752 /// <param name="remote_client"> 752 resultLocalIDs.Add(obj.LocalId);
753 /// A <see cref="IClientAPI"/> 753 }
754 /// </param> 754 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero)
755 public void SendLandObjectOwners(IClientAPI remote_client) 755 {
756 { 756 resultLocalIDs.Add(obj.LocalId);
757 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) 757 }
758 { 758 else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER &&
759 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>(); 759 obj.OwnerID != remote_client.AgentId)
760 List<UUID> groups = new List<UUID>(); 760 {
761 761 resultLocalIDs.Add(obj.LocalId);
762 lock (primsOverMe) 762 }
763 { 763 else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID))
764 try 764 {
765 { 765 resultLocalIDs.Add(obj.LocalId);
766 766 }
767 foreach (SceneObjectGroup obj in primsOverMe) 767 }
768 { 768 }
769 try 769 }
770 { 770 } catch (InvalidOperationException)
771 if (!primCount.ContainsKey(obj.OwnerID)) 771 {
772 { 772 m_log.Error("[LAND]: Unable to force select the parcel objects. Arr.");
773 primCount.Add(obj.OwnerID, 0); 773 }
774 } 774
775 } 775 remote_client.SendForceClientSelectObjects(resultLocalIDs);
776 catch (NullReferenceException) 776 }
777 { 777 }
778 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); 778
779 } 779 /// <summary>
780 try 780 /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes
781 { 781 /// aggreagete details such as the number of prims.
782 primCount[obj.OwnerID] += obj.PrimCount; 782 ///
783 } 783 /// </summary>
784 catch (KeyNotFoundException) 784 /// <param name="remote_client">
785 { 785 /// A <see cref="IClientAPI"/>
786 m_log.Error("[LAND]: Unable to match a prim with it's owner."); 786 /// </param>
787 } 787 public void SendLandObjectOwners(IClientAPI remote_client)
788 if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) 788 {
789 groups.Add(obj.OwnerID); 789 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this))
790 } 790 {
791 } 791 Dictionary<UUID, int> primCount = new Dictionary<UUID, int>();
792 catch (InvalidOperationException) 792 List<UUID> groups = new List<UUID>();
793 { 793
794 m_log.Error("[LAND]: Unable to Enumerate Land object arr."); 794 lock (primsOverMe)
795 } 795 {
796 } 796 try
797 797 {
798 remote_client.SendLandObjectOwners(LandData, groups, primCount); 798
799 } 799 foreach (SceneObjectGroup obj in primsOverMe)
800 } 800 {
801 801 try
802 public Dictionary<UUID, int> GetLandObjectOwners() 802 {
803 { 803 if (!primCount.ContainsKey(obj.OwnerID))
804 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>(); 804 {
805 lock (primsOverMe) 805 primCount.Add(obj.OwnerID, 0);
806 { 806 }
807 try 807 }
808 { 808 catch (NullReferenceException)
809 809 {
810 foreach (SceneObjectGroup obj in primsOverMe) 810 m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel");
811 { 811 }
812 if (!ownersAndCount.ContainsKey(obj.OwnerID)) 812 try
813 { 813 {
814 ownersAndCount.Add(obj.OwnerID, 0); 814 primCount[obj.OwnerID] += obj.PrimCount;
815 } 815 }
816 ownersAndCount[obj.OwnerID] += obj.PrimCount; 816 catch (KeyNotFoundException)
817 } 817 {
818 } 818 m_log.Error("[LAND]: Unable to match a prim with it's owner.");
819 catch (InvalidOperationException) 819 }
820 { 820 if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID)))
821 m_log.Error("[LAND]: Unable to enumerate land owners. arr."); 821 groups.Add(obj.OwnerID);
822 } 822 }
823 823 }
824 } 824 catch (InvalidOperationException)
825 return ownersAndCount; 825 {
826 } 826 m_log.Error("[LAND]: Unable to Enumerate Land object arr.");
827 827 }
828 #endregion 828 }
829 829
830 #region Object Returning 830 remote_client.SendLandObjectOwners(LandData, groups, primCount);
831 831 }
832 public void ReturnObject(SceneObjectGroup obj) 832 }
833 { 833
834 SceneObjectGroup[] objs = new SceneObjectGroup[1]; 834 public Dictionary<UUID, int> GetLandObjectOwners()
835 objs[0] = obj; 835 {
836 m_scene.returnObjects(objs, obj.OwnerID); 836 Dictionary<UUID, int> ownersAndCount = new Dictionary<UUID, int>();
837 } 837 lock (primsOverMe)
838 838 {
839 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) 839 try
840 { 840 {
841 Dictionary<UUID,List<SceneObjectGroup>> returns = 841
842 new Dictionary<UUID,List<SceneObjectGroup>>(); 842 foreach (SceneObjectGroup obj in primsOverMe)
843 843 {
844 lock (primsOverMe) 844 if (!ownersAndCount.ContainsKey(obj.OwnerID))
845 { 845 {
846 if (type == (uint)ObjectReturnType.Owner) 846 ownersAndCount.Add(obj.OwnerID, 0);
847 { 847 }
848 foreach (SceneObjectGroup obj in primsOverMe) 848 ownersAndCount[obj.OwnerID] += obj.PrimCount;
849 { 849 }
850 if (obj.OwnerID == m_landData.OwnerID) 850 }
851 { 851 catch (InvalidOperationException)
852 if (!returns.ContainsKey(obj.OwnerID)) 852 {
853 returns[obj.OwnerID] = 853 m_log.Error("[LAND]: Unable to enumerate land owners. arr.");
854 new List<SceneObjectGroup>(); 854 }
855 returns[obj.OwnerID].Add(obj); 855
856 } 856 }
857 } 857 return ownersAndCount;
858 } 858 }
859 else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) 859
860 { 860 #endregion
861 foreach (SceneObjectGroup obj in primsOverMe) 861
862 { 862 #region Object Returning
863 if (obj.GroupID == m_landData.GroupID) 863
864 { 864 public void ReturnObject(SceneObjectGroup obj)
865 if (!returns.ContainsKey(obj.OwnerID)) 865 {
866 returns[obj.OwnerID] = 866 SceneObjectGroup[] objs = new SceneObjectGroup[1];
867 new List<SceneObjectGroup>(); 867 objs[0] = obj;
868 returns[obj.OwnerID].Add(obj); 868 m_scene.returnObjects(objs, obj.OwnerID);
869 } 869 }
870 } 870
871 } 871 public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client)
872 else if (type == (uint)ObjectReturnType.Other) 872 {
873 { 873 Dictionary<UUID,List<SceneObjectGroup>> returns =
874 foreach (SceneObjectGroup obj in primsOverMe) 874 new Dictionary<UUID,List<SceneObjectGroup>>();
875 { 875
876 if (obj.OwnerID != m_landData.OwnerID && 876 lock (primsOverMe)
877 (obj.GroupID != m_landData.GroupID || 877 {
878 m_landData.GroupID == UUID.Zero)) 878 if (type == (uint)ObjectReturnType.Owner)
879 { 879 {
880 if (!returns.ContainsKey(obj.OwnerID)) 880 foreach (SceneObjectGroup obj in primsOverMe)
881 returns[obj.OwnerID] = 881 {
882 new List<SceneObjectGroup>(); 882 if (obj.OwnerID == m_landData.OwnerID)
883 returns[obj.OwnerID].Add(obj); 883 {
884 } 884 if (!returns.ContainsKey(obj.OwnerID))
885 } 885 returns[obj.OwnerID] =
886 } 886 new List<SceneObjectGroup>();
887 else if (type == (uint)ObjectReturnType.List) 887 returns[obj.OwnerID].Add(obj);
888 { 888 }
889 List<UUID> ownerlist = new List<UUID>(owners); 889 }
890 890 }
891 foreach (SceneObjectGroup obj in primsOverMe) 891 else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero)
892 { 892 {
893 if (ownerlist.Contains(obj.OwnerID)) 893 foreach (SceneObjectGroup obj in primsOverMe)
894 { 894 {
895 if (!returns.ContainsKey(obj.OwnerID)) 895 if (obj.GroupID == m_landData.GroupID)
896 returns[obj.OwnerID] = 896 {
897 new List<SceneObjectGroup>(); 897 if (!returns.ContainsKey(obj.OwnerID))
898 returns[obj.OwnerID].Add(obj); 898 returns[obj.OwnerID] =
899 } 899 new List<SceneObjectGroup>();
900 } 900 returns[obj.OwnerID].Add(obj);
901 } 901 }
902 } 902 }
903 903 }
904 foreach (List<SceneObjectGroup> ol in returns.Values) 904 else if (type == (uint)ObjectReturnType.Other)
905 { 905 {
906 if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) 906 foreach (SceneObjectGroup obj in primsOverMe)
907 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); 907 {
908 } 908 if (obj.OwnerID != m_landData.OwnerID &&
909 } 909 (obj.GroupID != m_landData.GroupID ||
910 910 m_landData.GroupID == UUID.Zero))
911 #endregion 911 {
912 912 if (!returns.ContainsKey(obj.OwnerID))
913 #region Object Adding/Removing from Parcel 913 returns[obj.OwnerID] =
914 914 new List<SceneObjectGroup>();
915 public void ResetLandPrimCounts() 915 returns[obj.OwnerID].Add(obj);
916 { 916 }
917 LandData.GroupPrims = 0; 917 }
918 LandData.OwnerPrims = 0; 918 }
919 LandData.OtherPrims = 0; 919 else if (type == (uint)ObjectReturnType.List)
920 LandData.SelectedPrims = 0; 920 {
921 921 List<UUID> ownerlist = new List<UUID>(owners);
922 922
923 lock (primsOverMe) 923 foreach (SceneObjectGroup obj in primsOverMe)
924 primsOverMe.Clear(); 924 {
925 } 925 if (ownerlist.Contains(obj.OwnerID))
926 926 {
927 public void AddPrimToCount(SceneObjectGroup obj) 927 if (!returns.ContainsKey(obj.OwnerID))
928 { 928 returns[obj.OwnerID] =
929 929 new List<SceneObjectGroup>();
930 UUID prim_owner = obj.OwnerID; 930 returns[obj.OwnerID].Add(obj);
931 int prim_count = obj.PrimCount; 931 }
932 932 }
933 if (obj.IsSelected) 933 }
934 { 934 }
935 LandData.SelectedPrims += prim_count; 935
936 } 936 foreach (List<SceneObjectGroup> ol in returns.Values)
937 else 937 {
938 { 938 if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol))
939 if (prim_owner == LandData.OwnerID) 939 m_scene.returnObjects(ol.ToArray(), remote_client.AgentId);
940 { 940 }
941 LandData.OwnerPrims += prim_count; 941 }
942 } 942
943 else if ((obj.GroupID == LandData.GroupID || 943 #endregion
944 prim_owner == LandData.GroupID) && 944
945 LandData.GroupID != UUID.Zero) 945 #region Object Adding/Removing from Parcel
946 { 946
947 LandData.GroupPrims += prim_count; 947 public void ResetLandPrimCounts()
948 } 948 {
949 else 949 LandData.GroupPrims = 0;
950 { 950 LandData.OwnerPrims = 0;
951 LandData.OtherPrims += prim_count; 951 LandData.OtherPrims = 0;
952 } 952 LandData.SelectedPrims = 0;
953 } 953
954 954
955 lock (primsOverMe) 955 lock (primsOverMe)
956 primsOverMe.Add(obj); 956 primsOverMe.Clear();
957 } 957 }
958 958
959 public void RemovePrimFromCount(SceneObjectGroup obj) 959 public void AddPrimToCount(SceneObjectGroup obj)
960 { 960 {
961 lock (primsOverMe) 961
962 { 962 UUID prim_owner = obj.OwnerID;
963 if (primsOverMe.Contains(obj)) 963 int prim_count = obj.PrimCount;
964 { 964
965 UUID prim_owner = obj.OwnerID; 965 if (obj.IsSelected)
966 int prim_count = obj.PrimCount; 966 {
967 967 LandData.SelectedPrims += prim_count;
968 if (prim_owner == LandData.OwnerID) 968 }
969 { 969 else
970 LandData.OwnerPrims -= prim_count; 970 {
971 } 971 if (prim_owner == LandData.OwnerID)
972 else if (obj.GroupID == LandData.GroupID || 972 {
973 prim_owner == LandData.GroupID) 973 LandData.OwnerPrims += prim_count;
974 { 974 }
975 LandData.GroupPrims -= prim_count; 975 else if ((obj.GroupID == LandData.GroupID ||
976 } 976 prim_owner == LandData.GroupID) &&
977 else 977 LandData.GroupID != UUID.Zero)
978 { 978 {
979 LandData.OtherPrims -= prim_count; 979 LandData.GroupPrims += prim_count;
980 } 980 }
981 981 else
982 primsOverMe.Remove(obj); 982 {
983 } 983 LandData.OtherPrims += prim_count;
984 } 984 }
985 } 985 }
986 986
987 #endregion 987 lock (primsOverMe)
988 988 primsOverMe.Add(obj);
989 #endregion 989 }
990 990
991 #endregion 991 public void RemovePrimFromCount(SceneObjectGroup obj)
992 992 {
993 /// <summary> 993 lock (primsOverMe)
994 /// Set the media url for this land parcel 994 {
995 /// </summary> 995 if (primsOverMe.Contains(obj))
996 /// <param name="url"></param> 996 {
997 public void SetMediaUrl(string url) 997 UUID prim_owner = obj.OwnerID;
998 { 998 int prim_count = obj.PrimCount;
999 LandData.MediaURL = url; 999
1000 SendLandUpdateToAvatarsOverMe(); 1000 if (prim_owner == LandData.OwnerID)
1001 } 1001 {
1002 1002 LandData.OwnerPrims -= prim_count;
1003 /// <summary> 1003 }
1004 /// Set the music url for this land parcel 1004 else if (obj.GroupID == LandData.GroupID ||
1005 /// </summary> 1005 prim_owner == LandData.GroupID)
1006 /// <param name="url"></param> 1006 {
1007 public void SetMusicUrl(string url) 1007 LandData.GroupPrims -= prim_count;
1008 { 1008 }
1009 LandData.MusicURL = url; 1009 else
1010 SendLandUpdateToAvatarsOverMe(); 1010 {
1011 } 1011 LandData.OtherPrims -= prim_count;
1012 } 1012 }
1013} 1013
1014 primsOverMe.Remove(obj);
1015 }
1016 }
1017 }
1018
1019 #endregion
1020
1021 #endregion
1022
1023 #endregion
1024
1025 /// <summary>
1026 /// Set the media url for this land parcel
1027 /// </summary>
1028 /// <param name="url"></param>
1029 public void SetMediaUrl(string url)
1030 {
1031 LandData.MediaURL = url;
1032 SendLandUpdateToAvatarsOverMe();
1033 }
1034
1035 /// <summary>
1036 /// Set the music url for this land parcel
1037 /// </summary>
1038 /// <param name="url"></param>
1039 public void SetMusicUrl(string url)
1040 {
1041 LandData.MusicURL = url;
1042 SendLandUpdateToAvatarsOverMe();
1043 }
1044 }
1045}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index cca296e..fc8e0d7 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2053,13 +2053,9 @@ namespace OpenSim.Region.Framework.Scenes
2053//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); 2053//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset);
2054 2054
2055 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child 2055 //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child
2056 Quaternion roffset = Quaternion.Identity; 2056 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2057 if (SitTargetisSet)
2058 {
2059 roffset = part.RotationOffset;
2060 }
2061 ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * roffset) + part.OffsetPosition), sitOrientation / part.RotationOffset, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook);
2062 2057
2058 m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target
2063 // This calls HandleAgentSit twice, once from here, and the client calls 2059 // This calls HandleAgentSit twice, once from here, and the client calls
2064 // HandleAgentSit itself after it gets to the location 2060 // HandleAgentSit itself after it gets to the location
2065 // It doesn't get to the location until we've moved them there though 2061 // It doesn't get to the location until we've moved them there though
@@ -2444,7 +2440,10 @@ namespace OpenSim.Region.Framework.Scenes
2444 } 2440 }
2445 2441
2446 m_linkedPrim = part.UUID; 2442 m_linkedPrim = part.UUID;
2447 m_offsetRotation = m_offsetRotation / part.RotationOffset; 2443 if (part.GetAvatarOnSitTarget() != UUID)
2444 {
2445 m_offsetRotation = m_offsetRotation / part.RotationOffset;
2446 }
2448 Velocity = Vector3.Zero; 2447 Velocity = Vector3.Zero;
2449 RemoveFromPhysicalScene(); 2448 RemoveFromPhysicalScene();
2450 Animator.TrySetMovementAnimation(sitAnimation); 2449 Animator.TrySetMovementAnimation(sitAnimation);