From 8d59385eeaa26feab8b19905ad6491065e4e4bf9 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 12:25:08 +0100 Subject: 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 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0ebcd8d..b209e23 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; -- cgit v1.1 From b6cd3b625ebffb45febf922a941fae337e3c1652 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 15:57:22 +0100 Subject: adding workaround for silent failure if position is outside the bounds of a region, implementing parcel prim count check. Signed-off-by: SignpostMarv --- .../Shared/Api/Implementation/LSL_Api.cs | 54 ++++++++++++++++------ 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b209e23..8163267 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1932,23 +1932,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api 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 - ) - ){ + + // BEGIN WORKAROUND + // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. + // + // This workaround is to prevent silent failure of this function. + // According to the specification on the SL Wiki, providing a position outside of the + if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) + { return 0; } + // END WORK AROUND + else{ + LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); + Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; + bool sameParcel = + llGetParcelDetails(new LSL_Vector(pos.x, pos.y, pos.z), parcelID).Data[0] == + llGetParcelDetails(pos, parcelID).Data[0] + ; + 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 + ) || + // BEGIN RELIANCE ON WORK AROUND + // this check will only work if pos is within the region bounds. + ( + !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. + (llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0) + m_host.ParentGroup.PrimCount) > llGetParcelMaxPrims(pos, 0) + ) + // END RELIANCE ON WORK-AROUND + ){ + return 0; + } + + SetPos(m_host.ParentGroup.RootPart, pos, false); - SetPos(m_host.ParentGroup.RootPart, pos, false); + return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + } - return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + return 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1 From e3453dd9ca1d08664a38205f05340623118a9880 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 12 Jul 2012 17:22:43 +0100 Subject: added in some extra variables, it sometimes thinks it is on the same parcel :( Signed-off-by: SignpostMarv --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8163267..ca240f5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1946,10 +1946,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else{ LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; - bool sameParcel = - llGetParcelDetails(new LSL_Vector(pos.x, pos.y, pos.z), parcelID).Data[0] == - llGetParcelDetails(pos, parcelID).Data[0] - ; + string parcelA = llGetParcelDetails(new LSL_Vector(objectPos.X, objectPos.X, objectPos.X), parcelID).Data[0].ToString(); + string parcelB = llGetParcelDetails(pos, parcelID).Data[0].ToString(); + bool sameParcel = parcelA == parcelB; + int objectPrimCount = m_host.ParentGroup.PrimCount; + LSL_Integer destParcelPrimCount = llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0); + LSL_Integer max = llGetParcelMaxPrims(pos, 0); if ( llGetStatus((int)PrimFlags.Physics) == 1 || // return FALSE if physical. m_host.ParentGroup.IsAttachment || // return FALSE if attachment @@ -1964,7 +1966,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // this check will only work if pos is within the region bounds. ( !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. - (llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0) + m_host.ParentGroup.PrimCount) > llGetParcelMaxPrims(pos, 0) + (destParcelPrimCount + objectPrimCount) > max ) // END RELIANCE ON WORK-AROUND ){ -- cgit v1.1 From 423101b425d84e98f88b9c438559fc3321297c51 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sat, 14 Jul 2012 01:14:00 +0100 Subject: acting on feedback from justincc --- .../Shared/Api/Implementation/LSL_Api.cs | 81 +++++++++++----------- 1 file changed, 42 insertions(+), 39 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ca240f5..cfcbae3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -421,15 +421,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return LSL_Vector.Norm(v); } - public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) + private double vecDist(LSL_Vector a, LSL_Vector b) { - m_host.AddScriptLPS(1); double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; return Math.Sqrt(dx * dx + dy * dy + dz * dz); } + public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) + { + m_host.AddScriptLPS(1); + return vecDist(a, b); + } + //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke /// @@ -1242,6 +1247,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + private bool isPhysical(){ + return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); + } + public LSL_Integer llGetStatus(int status) { m_host.AddScriptLPS(1); @@ -1249,11 +1258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (status) { case ScriptBaseClass.STATUS_PHYSICS: - if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics) - { - return 1; - } - return 0; + return isPhysical() ? 1 : 0; case ScriptBaseClass.STATUS_PHANTOM: if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) @@ -1943,42 +1948,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return 0; } // END WORK AROUND - else{ - LSL_List parcelID = new LSL_List(ScriptBaseClass.PARCEL_DETAILS_ID); - Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; - string parcelA = llGetParcelDetails(new LSL_Vector(objectPos.X, objectPos.X, objectPos.X), parcelID).Data[0].ToString(); - string parcelB = llGetParcelDetails(pos, parcelID).Data[0].ToString(); - bool sameParcel = parcelA == parcelB; - int objectPrimCount = m_host.ParentGroup.PrimCount; - LSL_Integer destParcelPrimCount = llGetParcelPrimCount(pos, ScriptBaseClass.PARCEL_COUNT_TOTAL, 0); - LSL_Integer max = llGetParcelMaxPrims(pos, 0); - 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 - ) || - // BEGIN RELIANCE ON WORK AROUND - // this check will only work if pos is within the region bounds. - ( - !sameParcel && // if it's moving within the same parcel we do not need to check if the destination parcel will exceed capacity if the object is moved. - (destParcelPrimCount + objectPrimCount) > max - ) - // END RELIANCE ON WORK-AROUND - ){ - return 0; - } + else if ( // this is not part of the workaround if-block because it's not related to the workaround. + isPhysical() || + 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; + } + + // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range. + // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read. - SetPos(m_host.ParentGroup.RootPart, pos, false); + Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; + LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); + LandData there = World.GetLandData((float)pos.x, (float)pos.y); - return llVecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits. + + bool sameParcel = here.GlobalID == there.GlobalID; + + if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) + { + return 0; } - return 0; + SetPos(m_host.ParentGroup.RootPart, pos, false); + + return vecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1 From 84b7ae25738c15737e70a680d1992cfbeb6cc806 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sat, 14 Jul 2012 01:41:51 +0100 Subject: acting on feedback from justincc --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cfcbae3..f88338d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -421,7 +421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return LSL_Vector.Norm(v); } - private double vecDist(LSL_Vector a, LSL_Vector b) + private double VecDist(LSL_Vector a, LSL_Vector b) { double dx = a.x - b.x; double dy = a.y - b.y; @@ -432,7 +432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) { m_host.AddScriptLPS(1); - return vecDist(a, b); + return VecDist(a, b); } //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke @@ -1247,7 +1247,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - private bool isPhysical(){ + private bool IsPhysical() + { return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); } @@ -1258,7 +1259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (status) { case ScriptBaseClass.STATUS_PHYSICS: - return isPhysical() ? 1 : 0; + return IsPhysical() ? 1 : 0; case ScriptBaseClass.STATUS_PHANTOM: if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) @@ -1949,7 +1950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // END WORK AROUND else if ( // this is not part of the workaround if-block because it's not related to the workaround. - isPhysical() || + IsPhysical() || m_host.ParentGroup.IsAttachment || // return FALSE if attachment ( pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. @@ -1981,7 +1982,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetPos(m_host.ParentGroup.RootPart, pos, false); - return vecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; + return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; } // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) -- cgit v1.1