diff options
Merge branch 'master' into careminster
Conflicts:
OpenSim/Framework/Watchdog.cs
OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
OpenSim/Region/Framework/Scenes/Scene.cs
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
OpenSim/Region/Framework/Scenes/ScenePresence.cs
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 129 |
1 files changed, 122 insertions, 7 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7b1f5d2..1f1caca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -147,6 +147,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
147 | get { return ParentGroup.RootPart == this; } | 147 | get { return ParentGroup.RootPart == this; } |
148 | } | 148 | } |
149 | 149 | ||
150 | /// <summary> | ||
151 | /// Is an explicit sit target set for this part? | ||
152 | /// </summary> | ||
153 | public bool IsSitTargetSet | ||
154 | { | ||
155 | get | ||
156 | { | ||
157 | return | ||
158 | !(SitTargetPosition == Vector3.Zero | ||
159 | && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion | ||
160 | || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point | ||
161 | || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion | ||
162 | } | ||
163 | } | ||
164 | |||
150 | #region Fields | 165 | #region Fields |
151 | 166 | ||
152 | public bool AllowedDrop; | 167 | public bool AllowedDrop; |
@@ -426,7 +441,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
426 | private uint _category; | 441 | private uint _category; |
427 | private Int32 _creationDate; | 442 | private Int32 _creationDate; |
428 | private uint _parentID = 0; | 443 | private uint _parentID = 0; |
429 | private UUID m_sitTargetAvatar = UUID.Zero; | ||
430 | private uint _baseMask = (uint)PermissionMask.All; | 444 | private uint _baseMask = (uint)PermissionMask.All; |
431 | private uint _ownerMask = (uint)PermissionMask.All; | 445 | private uint _ownerMask = (uint)PermissionMask.All; |
432 | private uint _groupMask = (uint)PermissionMask.None; | 446 | private uint _groupMask = (uint)PermissionMask.None; |
@@ -1312,13 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1312 | } | 1326 | } |
1313 | 1327 | ||
1314 | /// <summary> | 1328 | /// <summary> |
1315 | /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero | 1329 | /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero |
1316 | /// </summary> | 1330 | /// </summary> |
1317 | public UUID SitTargetAvatar | 1331 | public UUID SitTargetAvatar { get; set; } |
1318 | { | 1332 | |
1319 | get { return m_sitTargetAvatar; } | 1333 | /// <summary> |
1320 | set { m_sitTargetAvatar = value; } | 1334 | /// IDs of all avatars start on this object part. |
1321 | } | 1335 | /// </summary> |
1336 | /// <remarks> | ||
1337 | /// We need to track this so that we can stop sat upon prims from being attached. | ||
1338 | /// </remarks> | ||
1339 | /// <value> | ||
1340 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. | ||
1341 | /// </value> | ||
1342 | private HashSet<UUID> m_sittingAvatars; | ||
1322 | 1343 | ||
1323 | public virtual UUID RegionID | 1344 | public virtual UUID RegionID |
1324 | { | 1345 | { |
@@ -5128,5 +5149,99 @@ namespace OpenSim.Region.Framework.Scenes | |||
5128 | Inventory.UpdateInventoryItem(item, false, false); | 5149 | Inventory.UpdateInventoryItem(item, false, false); |
5129 | } | 5150 | } |
5130 | } | 5151 | } |
5152 | |||
5153 | /// <summary> | ||
5154 | /// Record an avatar sitting on this part. | ||
5155 | /// </summary> | ||
5156 | /// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks> | ||
5157 | /// <returns> | ||
5158 | /// true if the avatar was not already recorded, false otherwise. | ||
5159 | /// </returns> | ||
5160 | /// <param name='avatarId'></param> | ||
5161 | protected internal bool AddSittingAvatar(UUID avatarId) | ||
5162 | { | ||
5163 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | ||
5164 | SitTargetAvatar = avatarId; | ||
5165 | |||
5166 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5167 | |||
5168 | if (sittingAvatars == null) | ||
5169 | sittingAvatars = new HashSet<UUID>(); | ||
5170 | |||
5171 | lock (sittingAvatars) | ||
5172 | { | ||
5173 | m_sittingAvatars = sittingAvatars; | ||
5174 | return m_sittingAvatars.Add(avatarId); | ||
5175 | } | ||
5176 | } | ||
5177 | |||
5178 | /// <summary> | ||
5179 | /// Remove an avatar recorded as sitting on this part. | ||
5180 | /// </summary> | ||
5181 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5182 | /// <returns> | ||
5183 | /// true if the avatar was present and removed, false if it was not present. | ||
5184 | /// </returns> | ||
5185 | /// <param name='avatarId'></param> | ||
5186 | protected internal bool RemoveSittingAvatar(UUID avatarId) | ||
5187 | { | ||
5188 | if (SitTargetAvatar == avatarId) | ||
5189 | SitTargetAvatar = UUID.Zero; | ||
5190 | |||
5191 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5192 | |||
5193 | // This can occur under a race condition where another thread | ||
5194 | if (sittingAvatars == null) | ||
5195 | return false; | ||
5196 | |||
5197 | lock (sittingAvatars) | ||
5198 | { | ||
5199 | if (sittingAvatars.Remove(avatarId)) | ||
5200 | { | ||
5201 | if (sittingAvatars.Count == 0) | ||
5202 | m_sittingAvatars = null; | ||
5203 | |||
5204 | return true; | ||
5205 | } | ||
5206 | } | ||
5207 | |||
5208 | return false; | ||
5209 | } | ||
5210 | |||
5211 | /// <summary> | ||
5212 | /// Get a copy of the list of sitting avatars. | ||
5213 | /// </summary> | ||
5214 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5215 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> | ||
5216 | public HashSet<UUID> GetSittingAvatars() | ||
5217 | { | ||
5218 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5219 | |||
5220 | if (sittingAvatars == null) | ||
5221 | { | ||
5222 | return null; | ||
5223 | } | ||
5224 | else | ||
5225 | { | ||
5226 | lock (sittingAvatars) | ||
5227 | return new HashSet<UUID>(sittingAvatars); | ||
5228 | } | ||
5229 | } | ||
5230 | |||
5231 | /// <summary> | ||
5232 | /// Gets the number of sitting avatars. | ||
5233 | /// </summary> | ||
5234 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5235 | /// <returns></returns> | ||
5236 | public int GetSittingAvatarsCount() | ||
5237 | { | ||
5238 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5239 | |||
5240 | if (sittingAvatars == null) | ||
5241 | return 0; | ||
5242 | |||
5243 | lock (sittingAvatars) | ||
5244 | return sittingAvatars.Count; | ||
5245 | } | ||
5131 | } | 5246 | } |
5132 | } | 5247 | } |