From 33a894f3d2cc95a7a512b86f39f3c6a6afabb015 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 27 Aug 2011 00:15:21 +0100
Subject: refactor: move SOP.IsAttachment and AttachmentPoint up into SOG to
 avoid pointless duplication of identical values

---
 .../Caps/ObjectCaps/UploadObjectAssetModule.cs     |  2 +-
 .../Region/ClientStack/Linden/UDP/LLClientView.cs  | 10 +++--
 .../Avatar/Attachments/AttachmentsModule.cs        | 13 +++---
 .../Attachments/Tests/AttachmentsModuleTests.cs    | 18 ++++-----
 .../EntityTransfer/EntityTransferModule.cs         |  2 +-
 .../InventoryAccess/InventoryAccessModule.cs       |  2 +-
 OpenSim/Region/Framework/Scenes/Prioritizer.cs     |  8 ++--
 OpenSim/Region/Framework/Scenes/Scene.cs           |  4 +-
 .../Region/Framework/Scenes/SceneObjectGroup.cs    | 44 +++++++++------------
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 46 ++++++----------------
 .../Framework/Scenes/SceneObjectPartInventory.cs   |  2 +-
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   |  8 ++--
 OpenSim/Region/Framework/Scenes/SceneViewer.cs     |  3 +-
 .../Shared/Api/Implementation/LSL_Api.cs           | 20 +++++-----
 .../Api/Implementation/Plugins/SensorRepeat.cs     |  8 ++--
 15 files changed, 81 insertions(+), 109 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
index 8189518..c07fc73 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -330,7 +330,7 @@ namespace OpenSim.Region.ClientStack.Linden
                 grp.AbsolutePosition = obj.Position;
                 prim.RotationOffset = obj.Rotation;
                 
-                grp.RootPart.IsAttachment = false;
+                grp.IsAttachment = false;
                 // Required for linking
                 grp.RootPart.UpdateFlag = 0;
                 
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index f71871e..dc9a6ed 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4756,7 +4756,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             {
                 SceneObjectPart part = (SceneObjectPart)entity;
 
-                attachPoint = part.AttachmentPoint;
+                if (part.ParentGroup != null)
+                    attachPoint = part.ParentGroup.AttachmentPoint;
+                else
+                    attachPoint = 0;
+
                 collisionPlane = Vector4.Zero;
                 position = part.RelativePosition;
                 velocity = part.Velocity;
@@ -4913,10 +4917,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             //update.JointType = 0;
             update.Material = data.Material;
             update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
-            if (data.IsAttachment)
+            if (data.ParentGroup != null && data.ParentGroup.IsAttachment)
             {
                 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
-                update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
+                update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
             }
             else
             {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 3e1cb02..b976020 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -369,11 +369,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             SceneObjectGroup att, ScenePresence sp, UUID itemID, uint AttachmentPt)
         {
 //            m_log.DebugFormat(
-//                "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})", 
-//                remoteClient.Name, att.Name, itemID);
+//                "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} {2} (item ID {3}) at {4}",
+//                sp.Name, att.Name, att.LocalId, itemID, AttachmentPt);
             
             if (!att.IsDeleted)
-                AttachmentPt = att.RootPart.AttachmentPoint;
+                AttachmentPt = att.AttachmentPoint;
 
             InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
             item = m_scene.InventoryService.GetItem(item);
@@ -547,7 +547,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
                         );
 
                         group.RootPart.SetParentLocalId(0);
-                        group.RootPart.IsAttachment = false;
+                        group.IsAttachment = false;
                         group.AbsolutePosition = group.RootPart.AttachedPos;
 
                         UpdateKnownItem(sp.ControllingClient, group, group.GetFromItemID(), group.OwnerID);
@@ -569,7 +569,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             // Finally, we restore the object's attachment status.
             byte attachmentPoint = sog.GetAttachmentPoint();
             sog.UpdateGroupPosition(pos);
-            sog.RootPart.IsAttachment = false;
+            sog.IsAttachment = false;
             sog.AbsolutePosition = sog.RootPart.AttachedPos;
             sog.SetAttachmentPoint(attachmentPoint);                                       
             sog.HasGroupChanged = true;            
@@ -666,8 +666,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
 
             so.AbsolutePosition = attachOffset;
             so.RootPart.AttachedPos = attachOffset;
-            so.RootPart.IsAttachment = true;
-
+            so.IsAttachment = true;
             so.RootPart.SetParentLocalId(avatar.LocalId);
             so.SetAttachmentPoint(Convert.ToByte(attachmentpoint));
 
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index b7d21fd..790a651 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -110,6 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(attachments.Count, Is.EqualTo(1));
             SceneObjectGroup attSo = attachments[0];
             Assert.That(attSo.Name, Is.EqualTo(attName));
+            Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.IsAttachment);
             Assert.That(attSo.UsesPhysics, Is.False);
@@ -132,9 +133,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             UUID attAssetId = TestHelpers.ParseTail(0x3);
             string attName = "att";
 
-            InventoryItemBase attItem
-                = UserInventoryHelpers.CreateInventoryItem(
-                    scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
+            UserInventoryHelpers.CreateInventoryItem(
+                scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
 
             m_attMod.RezSingleAttachmentFromInventory(
                 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -145,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(attachments.Count, Is.EqualTo(1));
             SceneObjectGroup attSo = attachments[0];
             Assert.That(attSo.Name, Is.EqualTo(attName));
+            Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.IsAttachment);
             Assert.That(attSo.UsesPhysics, Is.False);
@@ -166,9 +167,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             UUID attAssetId = TestHelpers.ParseTail(0x3);
             string attName = "att";
 
-            InventoryItemBase attItem
-                = UserInventoryHelpers.CreateInventoryItem(
-                    scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
+            UserInventoryHelpers.CreateInventoryItem(
+                scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
 
             UUID attSoId = m_attMod.RezSingleAttachmentFromInventory(
                 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -198,9 +198,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             UUID attAssetId = TestHelpers.ParseTail(0x3);
             string attName = "att";
 
-            InventoryItemBase attItem
-                = UserInventoryHelpers.CreateInventoryItem(
-                    scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
+            UserInventoryHelpers.CreateInventoryItem(
+                scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
 
             m_attMod.RezSingleAttachmentFromInventory(
                 m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
@@ -242,6 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(attachments.Count, Is.EqualTo(1));
             SceneObjectGroup attSo = attachments[0];
             Assert.That(attSo.Name, Is.EqualTo(attName));
+            Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.GetAttachmentPoint(), Is.EqualTo((byte)AttachmentPoint.Chest));
             Assert.That(attSo.IsAttachment);
             Assert.That(attSo.UsesPhysics, Is.False);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f5d49c5..7963e53 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1782,7 +1782,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                         // Set the parent localID to 0 so it transfers over properly.
                         gobj.RootPart.SetParentLocalId(0);
                         gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
-                        gobj.RootPart.IsAttachment = false;
+                        gobj.IsAttachment = false;
                         //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
                         m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
                         CrossPrimGroupIntoNewRegion(destination, gobj, silent);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 65ba87b..fcb7eea 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -841,7 +841,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
                         if (attachment)
                         {
                             group.RootPart.Flags |= PrimFlags.Phantom;
-                            group.RootPart.IsAttachment = true;
+                            group.IsAttachment = true;
                         }
 
                         // If we're rezzing an attachment then don't ask
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
index 2a76755..33407ec 100644
--- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (entity is SceneObjectPart)
             {
                 SceneObjectPart sop = (SceneObjectPart)entity;
-                if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
+                if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
                     return 1;
             }
 
@@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (entity is SceneObjectPart)
             {
                 SceneObjectPart sop = (SceneObjectPart)entity;
-                if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
+                if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
                     return 1;
             }
 
@@ -148,7 +148,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (entity is SceneObjectPart)
             {
                 SceneObjectPart sop = (SceneObjectPart)entity;
-                if (sop.ParentGroup.RootPart.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
+                if (sop.ParentGroup.IsAttachment && client.AgentId == sop.ParentGroup.AttachedAvatar)
                     return 1;
             }
 
@@ -171,7 +171,7 @@ namespace OpenSim.Region.Framework.Scenes
                     if (entity is SceneObjectPart)
                     {
                         // Attachments are high priority, 
-                        if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment)
+                        if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
                             return 1;
 
                         // Non physical prims are lower priority than physical prims
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 513c0ea..45d1a0e 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4223,7 +4223,7 @@ namespace OpenSim.Region.Framework.Scenes
                 //  their scripts will actually run.
                 //      -- Leaf, Tue Aug 12 14:17:05 EDT 2008
                 SceneObjectPart parent = part.ParentGroup.RootPart;
-                if (parent != null && parent.IsAttachment)
+                if (parent != null && part.ParentGroup.IsAttachment)
                     return ScriptDanger(parent, parent.GetWorldPosition());
                 else
                     return ScriptDanger(part, part.GetWorldPosition());
@@ -5030,7 +5030,7 @@ namespace OpenSim.Region.Framework.Scenes
                                     delete = true;
                             }
 
-                            if (delete && !rootPart.IsAttachment && !deletes.Contains(g))
+                            if (delete && !g.IsAttachment && !deletes.Contains(g))
                                 deletes.Add(g);
                         });
                 break;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index fada688..34f484d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -146,27 +146,11 @@ namespace OpenSim.Region.Framework.Scenes
                 return true;
             return false;
         }
-        
+
         /// <summary>
         /// Is this scene object acting as an attachment?
         /// </summary>
-        /// <remarks>
-        /// We return false if the group has already been deleted.
-        ///
-        /// TODO: At the moment set must be done on the part itself.  There may be a case for doing it here since I
-        /// presume either all or no parts in a linkset can be part of an attachment (in which
-        /// case the value would get proprogated down into all the descendent parts).
-        /// </remarks>
-        public bool IsAttachment
-        {
-            get
-            {
-                if (!IsDeleted)
-                    return m_rootPart.IsAttachment;
-                
-                return false;
-            }
-        }
+        public bool IsAttachment { get; set; }
 
         /// <summary>
         /// The avatar to which this scene object is attached.
@@ -177,6 +161,14 @@ namespace OpenSim.Region.Framework.Scenes
         public UUID AttachedAvatar { get; set; }
 
         /// <summary>
+        /// Attachment point of this scene object to an avatar.
+        /// </summary>
+        /// <remarks>
+        /// 0 if we're not attached to anything
+        /// </remarks>
+        public uint AttachmentPoint;
+
+        /// <summary>
         /// Is this scene object phantom?
         /// </summary>
         /// <remarks>
@@ -354,11 +346,13 @@ namespace OpenSim.Region.Framework.Scenes
         /// <summary>
         /// Check both the attachment property and the relevant properties of the underlying root part.
         /// </summary>
+        /// <remarks>
         /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't
         /// have the IsAttachment property yet checked.
         /// 
         /// FIXME: However, this should be fixed so that this property
         /// propertly reflects the underlying status.
+        /// </remarks>
         /// <returns></returns>
         public bool IsAttachmentCheckFull()
         {
@@ -987,11 +981,11 @@ namespace OpenSim.Region.Framework.Scenes
             return m_rootPart.Shape.State;
         }
 
-        public void SetAttachmentPoint(byte point)
+        public void SetAttachmentPoint(uint point)
         {
-            SceneObjectPart[] parts = m_parts.GetArray();
-            for (int i = 0; i < parts.Length; i++)
-                parts[i].SetAttachmentPoint(point);
+            AttachmentPoint = point;
+            IsAttachment = point != 0;
+            m_rootPart.Shape.State = (byte)point;
         }
 
         public void ClearPartAttachmentData()
@@ -1424,16 +1418,16 @@ namespace OpenSim.Region.Framework.Scenes
 
             // This is only necessary when userExposed is false!
 
-            bool previousAttachmentStatus = dupe.RootPart.IsAttachment;
+            bool previousAttachmentStatus = dupe.IsAttachment;
             
             if (!userExposed)
-                dupe.RootPart.IsAttachment = true;
+                dupe.IsAttachment = true;
 
             dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
 
             if (!userExposed)
             {
-                dupe.RootPart.IsAttachment = previousAttachmentStatus;
+                dupe.IsAttachment = previousAttachmentStatus;
             }
 
             dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index e510611..71023a9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -213,10 +213,7 @@ namespace OpenSim.Region.Framework.Scenes
         {
             get { return m_fromUserInventoryItemID; }
         }
-
         
-        public bool IsAttachment;
-
         
         public scriptEvents AggregateScriptEvents;
 
@@ -224,9 +221,6 @@ namespace OpenSim.Region.Framework.Scenes
         public Vector3 AttachedPos;
 
         
-        public uint AttachmentPoint;
-
-        
         public Vector3 RotationAxis = Vector3.One;
 
         
@@ -723,7 +717,7 @@ namespace OpenSim.Region.Framework.Scenes
                     m_groupPosition = actor.Position;
                 }
 
-                if (IsAttachment)
+                if (m_parentGroup.IsAttachment)
                 {
                     ScenePresence sp = m_parentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
                     if (sp != null)
@@ -807,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes
             {
                 if (IsRoot)
                 {
-                    if (IsAttachment)
+                    if (m_parentGroup.IsAttachment)
                         return AttachedPos;
                     else
                         return AbsolutePosition;
@@ -1090,7 +1084,7 @@ namespace OpenSim.Region.Framework.Scenes
         {
             get
             {
-                if (IsAttachment)
+                if (m_parentGroup.IsAttachment)
                     return GroupPosition;
 
                 return m_offsetPosition + m_groupPosition;
@@ -1588,7 +1582,7 @@ namespace OpenSim.Region.Framework.Scenes
 
                 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
                 // or flexible
-                if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
+                if (!isPhantom && !m_parentGroup.IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
                 {
                     try
                     {
@@ -2880,7 +2874,7 @@ namespace OpenSim.Region.Framework.Scenes
 
         public void rotLookAt(Quaternion target, float strength, float damping)
         {
-            if (IsAttachment)
+            if (m_parentGroup.IsAttachment)
             {
                 /*
                     ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
@@ -3014,7 +3008,7 @@ namespace OpenSim.Region.Framework.Scenes
             
             if (IsRoot)
             {
-                if (IsAttachment)
+                if (m_parentGroup.IsAttachment)
                 {
                     SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
                 }
@@ -3076,7 +3070,7 @@ namespace OpenSim.Region.Framework.Scenes
         {
             // Suppress full updates during attachment editing
             //
-            if (ParentGroup.IsSelected && IsAttachment)
+            if (ParentGroup.IsSelected && ParentGroup.IsAttachment)
                 return;
             
             if (ParentGroup.IsDeleted)
@@ -3254,26 +3248,6 @@ namespace OpenSim.Region.Framework.Scenes
             });
         }
 
-        public void SetAttachmentPoint(uint AttachmentPoint)
-        {
-            this.AttachmentPoint = AttachmentPoint;
-
-            if (AttachmentPoint != 0)
-            {
-                IsAttachment = true;
-            }
-            else
-            {
-                IsAttachment = false;
-            }
-
-            // save the attachment point.
-            //if (AttachmentPoint != 0)
-            //{
-                m_shape.State = (byte)AttachmentPoint;
-            //}
-        }
-
         public void SetAxisRotation(int axis, int rotate)
         {
             if (m_parentGroup != null)
@@ -4497,7 +4471,9 @@ namespace OpenSim.Region.Framework.Scenes
                 }
             }
 
-            if (SetPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
+            if (SetPhantom
+                || ParentGroup.IsAttachment
+                || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
             {
                 AddFlag(PrimFlags.Phantom);
                 if (PhysActor != null)
@@ -4928,7 +4904,7 @@ namespace OpenSim.Region.Framework.Scenes
             if (ParentGroup == null || ParentGroup.IsDeleted)
                 return;
 
-            if (IsAttachment && ParentGroup.RootPart != this)
+            if (ParentGroup.IsAttachment && ParentGroup.RootPart != this)
                 return;
             
             // Causes this thread to dig into the Client Thread Data.
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3b60f8c..108089e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -201,7 +201,7 @@ namespace OpenSim.Region.Framework.Scenes
             // Don't let this set the HasGroupChanged flag for attachments
             // as this happens during rez and we don't want a new asset
             // for each attachment each time
-            if (!m_part.ParentGroup.RootPart.IsAttachment)
+            if (!m_part.ParentGroup.IsAttachment)
             {
                 HasInventoryChanged = true;
                 m_part.ParentGroup.HasGroupChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index fc89473..93782ce 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3178,7 +3178,7 @@ namespace OpenSim.Region.Framework.Scenes
                     ISceneObject clone = sog.CloneForNewScene();
                     // Attachment module assumes that GroupPosition holds the offsets...!
                     ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
-                    ((SceneObjectGroup)clone).RootPart.IsAttachment = false;
+                    ((SceneObjectGroup)clone).IsAttachment = false;
                     cAgent.AttachmentObjects.Add(clone);
                     string state = sog.GetStateSnapshot();
                     cAgent.AttachmentObjectStates.Add(state);
@@ -3477,7 +3477,7 @@ namespace OpenSim.Region.Framework.Scenes
             {
                 foreach (SceneObjectGroup so in m_attachments)
                 {
-                    if (attachmentPoint == so.RootPart.AttachmentPoint)
+                    if (attachmentPoint == so.AttachmentPoint)
                         attachments.Add(so);
                 }
             }
@@ -3869,12 +3869,12 @@ namespace OpenSim.Region.Framework.Scenes
                 {
                     if (grp.HasGroupChanged) // Resizer scripts?
                     {
-                        grp.RootPart.IsAttachment = false;
+                        grp.IsAttachment = false;
                         grp.AbsolutePosition = grp.RootPart.AttachedPos;
 //                        grp.DetachToInventoryPrep();
                         attachmentsModule.UpdateKnownItem(ControllingClient,
                                 grp, grp.GetFromItemID(), grp.OwnerID);
-                        grp.RootPart.IsAttachment = true;
+                        grp.IsAttachment = true;
                     }
                 }
             }
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 7c067ca..997845b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -120,8 +120,7 @@ namespace OpenSim.Region.Framework.Scenes
                         // We deal with the possibility that two updates occur at
                         // the same unix time at the update point itself.
 
-                        if ((update.LastFullUpdateTime < part.TimeStampFull) ||
-                                part.IsAttachment)
+                        if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment)
                         {
     //                            m_log.DebugFormat(
     //                                "[SCENE PRESENCE]: Fully   updating prim {0}, {1} - part timestamp {2}",
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 81f1f38..a7f08d9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1965,7 +1965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             if (part.ParentGroup.RootPart == part)
             {
-                if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0)
+                if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
                     targetPos.z = ground;
                 SceneObjectGroup parent = part.ParentGroup;
                 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
@@ -2097,7 +2097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             Quaternion q;
             if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
             {
-                if (part.ParentGroup.RootPart.AttachmentPoint != 0)
+                if (part.ParentGroup.AttachmentPoint != 0)
                 {
                     ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
                     if (avatar != null)
@@ -2241,7 +2241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             Vector3 vel;
 
-            if (m_host.IsAttachment)
+            if (m_host.ParentGroup.IsAttachment)
             {
                 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
                 vel = avatar.Velocity;
@@ -2997,7 +2997,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             m_host.AddScriptLPS(1);
 
-            if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
+            if (m_host.ParentGroup.AttachmentPoint == 0)
                 return;
 
             TaskInventoryItem item;
@@ -3587,7 +3587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
 
-            if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0)
+            if (targetPart.ParentGroup.AttachmentPoint != 0)
                 return; // Fail silently if attached
             SceneObjectGroup parentPrim = null, childPrim = null;
 
@@ -3640,7 +3640,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             SceneObjectGroup parentPrim = m_host.ParentGroup;
 
-            if (parentPrim.RootPart.AttachmentPoint != 0)
+            if (parentPrim.AttachmentPoint != 0)
                 return; // Fail silently if attached
             SceneObjectPart childPrim = null;
 
@@ -3710,7 +3710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             m_host.AddScriptLPS(1);
             SceneObjectGroup parentPrim = m_host.ParentGroup;
-            if (parentPrim.RootPart.AttachmentPoint != 0)
+            if (parentPrim.AttachmentPoint != 0)
                 return; // Fail silently if attached
 
             List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
@@ -4349,7 +4349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                     return;
 
                 // Object not pushable.  Not an attachment and has no physics component
-                if (!pusheeob.IsAttachment && pusheeob.PhysActor == null)
+                if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
                     return;
 
                 PusheePos = pusheeob.AbsolutePosition;
@@ -5857,7 +5857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public LSL_Integer llGetAttached()
         {
             m_host.AddScriptLPS(1);
-            return m_host.ParentGroup.RootPart.AttachmentPoint;
+            return m_host.ParentGroup.AttachmentPoint;
         }
 
         public LSL_Integer llGetFreeMemory()
@@ -7458,7 +7458,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             m_host.AddScriptLPS(1);
             Quaternion q;
-            if (m_host.ParentGroup.RootPart.AttachmentPoint != 0)
+            if (m_host.ParentGroup.AttachmentPoint != 0)
             {
                 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
                 if (avatar != null)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index bf74760..4ac7f8b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -303,7 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             float dz;
 
             Quaternion q = SensePoint.RotationOffset;
-            if (SensePoint.ParentGroup.RootPart.IsAttachment)
+            if (SensePoint.ParentGroup.IsAttachment)
             {
                 // In attachments, the sensor cone always orients with the
                 // avatar rotation. This may include a nonzero elevation if
@@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
                     objtype = 0;
 
                     part = ((SceneObjectGroup)ent).RootPart;
-                    if (part.AttachmentPoint != 0) // Attached so ignore
+                    if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
                         continue;
 
                     if (part.Inventory.ContainsScripts())
@@ -423,7 +423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             Vector3 fromRegionPos = SensePoint.AbsolutePosition;
             
             Quaternion q = SensePoint.RotationOffset;
-            if (SensePoint.ParentGroup.RootPart.IsAttachment)
+            if (SensePoint.ParentGroup.IsAttachment)
             {
                 // In attachments, the sensor cone always orients with the
                 // avatar rotation. This may include a nonzero elevation if
@@ -435,7 +435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
             LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
             double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
-            bool attached = (SensePoint.AttachmentPoint != 0);
+            bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
             Vector3 toRegionPos;
             double dis;
 
-- 
cgit v1.1