From 8d59385eeaa26feab8b19905ad6491065e4e4bf9 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 12:25:08 +0100 Subject: [PATCH] Implementation of llSetRegionPos(). Does not implement failure on object entry/prim limit/access restrictions. Signed-off-by: SignpostMarv --- .../Shared/Api/Implementation/LSL_Api.cs | 43 +++++++++++++++++-- .../Shared/Api/Interface/ILSL_Api.cs | 1 + .../Shared/Api/Runtime/LSL_Stub.cs | 5 +++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0ebcd8dbe6..b209e23a23 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1917,11 +1917,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - SetPos(m_host, pos); + SetPos(m_host, pos, true); ScriptSleep(200); } + /// + /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos + /// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into. + /// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking. + /// + /// + /// 1 if successful, 0 otherwise. + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + m_host.AddScriptLPS(1); + if ( + llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. + m_host.ParentGroup.IsAttachment || // return FALSE if attachment + ( + pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. + pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. + pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. + pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. + pos.z > 4096 // return FALSE if altitude than 4096m + ) + ){ + return 0; + } + + SetPos(m_host.ParentGroup.RootPart, pos, false); + + return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + } + // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) // note linked setpos is capped "differently" private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) @@ -1953,7 +1982,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return real_vec; } - protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) + /// + /// set object position, optionally capping the distance. + /// + /// + /// + /// if TRUE, will cap the distance to 10m. + protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) { // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) LSL_Vector currentPos = GetPartLocalPos(part); @@ -1966,12 +2001,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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); + LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); } else { - LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); + LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); SceneObjectGroup parent = part.ParentGroup; parent.HasGroupChanged = true; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index d39b20454c..3fb463b766 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -359,6 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetPrimitiveParams(LSL_List rules); void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); void llSetPrimURL(string url); + LSL_Integer llSetRegionPos(LSL_Vector pos); void llSetRemoteScriptAccessPin(int pin); void llSetRot(LSL_Rotation rot); void llSetScale(LSL_Vector scale); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index a0b3bc8d4c..c4578804c2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1618,6 +1618,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetPrimURL(url); } + public LSL_Integer llSetRegionPos(LSL_Vector pos) + { + return m_LSL_Functions.llSetRegionPos(pos); + } + public void llSetRemoteScriptAccessPin(int pin) { m_LSL_Functions.llSetRemoteScriptAccessPin(pin);