From 099212167b2b3d5f8bdf529d24a6c47536716706 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 29 Aug 2014 23:40:21 +0100 Subject: [PATCH] Implement STATUS_BLOCK_GRAB_OBJECT in llSetStatus()/llGetStatus() and correct effect of STATUS_BLOCK_GRAB As per http://wiki.secondlife.com/wiki/LlSetStatus Setting STATUS_BLOCK_GRAB_OBJECT prevents or allows move of a physical linkset by grab on any prim. Setting STATUS_BLOCK_GRAB prevents or allows move of a physical linkset by grab on a particular prim. Previously, setting STATUS_BLOCK_GRAB would prevent drag via all prims of the linkset. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 3 ++- .../Framework/Scenes/SceneObjectGroup.cs | 16 ++++++++++++++-- .../Region/Framework/Scenes/SceneObjectPart.cs | 18 +----------------- .../Shared/Api/Implementation/LSL_Api.cs | 18 ++++++++---------- .../Shared/Api/Runtime/LSL_Constants.cs | 1 + 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 3678c7e5c4..51f50d9ea8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1446,8 +1446,9 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId))// && PermissionsMngr.) { - group.GrabMovement(offset, pos, remoteClient); + group.GrabMovement(objectID, offset, pos, remoteClient); } + // This is outside the above permissions condition // so that if the object is locked the client moving the object // get's it's position on the simulator even if it was the same as before diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index e37bbd81b6..2aeccd8ab3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -827,6 +827,12 @@ namespace OpenSim.Region.Framework.Scenes /// public UUID FromFolderID { get; set; } + /// + /// If true then grabs are blocked no matter what the individual part BlockGrab setting. + /// + /// true if block grab override; otherwise, false. + public bool BlockGrabOverride { get; set; } + /// /// IDs of all avatars sat on this scene object. /// @@ -2610,20 +2616,26 @@ namespace OpenSim.Region.Framework.Scenes /// If object is physical, apply force to move it around /// If object is not physical, just put it at the resulting location /// + /// Part ID to check for grab /// Always seems to be 0,0,0, so ignoring /// New position. We do the math here to turn it into a force /// - public void GrabMovement(Vector3 offset, Vector3 pos, IClientAPI remoteClient) + public void GrabMovement(UUID partID, Vector3 offset, Vector3 pos, IClientAPI remoteClient) { if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) { + SceneObjectPart part = GetPart(partID); + + if (part == null) + return; + PhysicsActor pa = m_rootPart.PhysActor; if (pa != null) { if (pa.IsPhysical) { - if (!m_rootPart.BlockGrab) + if (!BlockGrabOverride && !part.BlockGrab) { Vector3 llmoveforce = pos - AbsolutePosition; Vector3 grabforce = llmoveforce; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 05e3ee906e..8785ca97d8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -186,7 +186,7 @@ namespace OpenSim.Region.Framework.Scenes public bool RETURN_AT_EDGE; - public bool BlockGrab; + public bool BlockGrab { get; set; } public bool StatusSandbox; @@ -2079,22 +2079,6 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.RootPart.RETURN_AT_EDGE = p; } - public bool GetBlockGrab() - { - if (ParentGroup.IsDeleted) - return false; - - return ParentGroup.RootPart.BlockGrab; - } - - public void SetBlockGrab(bool p) - { - if (ParentGroup.IsDeleted) - return; - - ParentGroup.RootPart.BlockGrab = p; - } - public void SetStatusSandbox(bool p) { if (ParentGroup.IsDeleted) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 50e4804ef0..5aef892eb9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1377,12 +1377,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if ((status & ScriptBaseClass.STATUS_BLOCK_GRAB) == ScriptBaseClass.STATUS_BLOCK_GRAB) - { - if (value != 0) - m_host.SetBlockGrab(true); - else - m_host.SetBlockGrab(false); - } + m_host.BlockGrab = value != 0; + + if ((status & ScriptBaseClass.STATUS_BLOCK_GRAB_OBJECT) == ScriptBaseClass.STATUS_BLOCK_GRAB_OBJECT) + m_host.ParentGroup.BlockGrabOverride = value != 0; if ((status & ScriptBaseClass.STATUS_DIE_AT_EDGE) == ScriptBaseClass.STATUS_DIE_AT_EDGE) { @@ -1443,10 +1441,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 0; case ScriptBaseClass.STATUS_BLOCK_GRAB: - if (m_host.GetBlockGrab()) - return 1; - else - return 0; + return m_host.BlockGrab ? 1 : 0; + + case ScriptBaseClass.STATUS_BLOCK_GRAB_OBJECT: + return m_host.ParentGroup.BlockGrabOverride ? 1 : 0; case ScriptBaseClass.STATUS_DIE_AT_EDGE: if (m_host.GetDieAtEdge()) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 7d80dcbf27..a96cd16355 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -48,6 +48,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int STATUS_DIE_AT_EDGE = 128; public const int STATUS_RETURN_AT_EDGE = 256; public const int STATUS_CAST_SHADOWS = 512; + public const int STATUS_BLOCK_GRAB_OBJECT = 1024; public const int AGENT = 1; public const int AGENT_BY_LEGACY_NAME = 1;