diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a7341a9a5a..d0430f476e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2177,6 +2177,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return real_vec; } + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + return new LSL_Integer(SetRegionPos(m_host, pos)); + } + + protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return 0; + + SceneObjectGroup grp = part.ParentGroup; + + if (grp.IsAttachment) + return 0; + + if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical) + return 0; + + if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f) + return 0; + + float constrainedX = (float)targetPos.x; + float constrainedY = (float)targetPos.y; + + if (constrainedX < 0.0f) + constrainedX = 0.0f; + if (constrainedY < 0.0f) + constrainedY = 0.0f; + if (constrainedX >= (float)Constants.RegionSize) + constrainedX = (float)Constants.RegionSize - 0.1f; + if (constrainedY >= (float)Constants.RegionSize) + constrainedY = (float)Constants.RegionSize -0.1f; + + float ground = World.GetGroundHeight(constrainedX, constrainedY); + + if (targetPos.z < ground) + targetPos.z = ground; + + Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); + + if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest)) + return 0; + + grp.UpdateGroupPosition(dest); + + return 1; + } + protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) { if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) @@ -2185,11 +2233,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Vector currentPos = GetPartLocalPos(part); LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos); + if (part.ParentGroup.RootPart == part) { SceneObjectGroup parent = part.ParentGroup; + Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); + if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest)) + return; Util.FireAndForget(delegate(object x) { - parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z)); + parent.UpdateGroupPosition(dest); }); } else diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index f2d4399fd7..967979804c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -346,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetParcelMusicURL(string url); void llSetPayPrice(int price, LSL_List quick_pay_buttons); void llSetPos(LSL_Vector pos); + LSL_Integer llSetRegionPos(LSL_Vector pos); LSL_Integer llSetPrimMediaParams(int face, LSL_List rules); void llSetPrimitiveParams(LSL_List rules); void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index fad6c350b4..dcaa3b4747 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1580,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetPos(pos); } + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + return m_LSL_Functions.llSetRegionPos(pos); + } + public void llSetPrimitiveParams(LSL_List rules) { m_LSL_Functions.llSetPrimitiveParams(rules);