aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs135
1 files changed, 78 insertions, 57 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index fed3122..a43a8bb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -517,15 +517,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
517 return LSL_Vector.Norm(v); 517 return LSL_Vector.Norm(v);
518 } 518 }
519 519
520 public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) 520 private double VecDist(LSL_Vector a, LSL_Vector b)
521 { 521 {
522 m_host.AddScriptLPS(1);
523 double dx = a.x - b.x; 522 double dx = a.x - b.x;
524 double dy = a.y - b.y; 523 double dy = a.y - b.y;
525 double dz = a.z - b.z; 524 double dz = a.z - b.z;
526 return Math.Sqrt(dx * dx + dy * dy + dz * dz); 525 return Math.Sqrt(dx * dx + dy * dy + dz * dz);
527 } 526 }
528 527
528 public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
529 {
530 m_host.AddScriptLPS(1);
531 return VecDist(a, b);
532 }
533
529 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
530 535
531 // Utility function for llRot2Euler 536 // Utility function for llRot2Euler
@@ -1391,6 +1396,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1391 } 1396 }
1392 } 1397 }
1393 1398
1399 private bool IsPhysical()
1400 {
1401 return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics);
1402 }
1403
1394 public LSL_Integer llGetStatus(int status) 1404 public LSL_Integer llGetStatus(int status)
1395 { 1405 {
1396 m_host.AddScriptLPS(1); 1406 m_host.AddScriptLPS(1);
@@ -1398,11 +1408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1398 switch (status) 1408 switch (status)
1399 { 1409 {
1400 case ScriptBaseClass.STATUS_PHYSICS: 1410 case ScriptBaseClass.STATUS_PHYSICS:
1401 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics) 1411 return IsPhysical() ? 1 : 0;
1402 {
1403 return 1;
1404 }
1405 return 0;
1406 1412
1407 case ScriptBaseClass.STATUS_PHANTOM: 1413 case ScriptBaseClass.STATUS_PHANTOM:
1408 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) 1414 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom)
@@ -2155,11 +2161,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2155 { 2161 {
2156 m_host.AddScriptLPS(1); 2162 m_host.AddScriptLPS(1);
2157 2163
2158 SetPos(m_host, pos); 2164 SetPos(m_host, pos, true);
2159 2165
2160 ScriptSleep(200); 2166 ScriptSleep(200);
2161 } 2167 }
2162 2168
2169 /// <summary>
2170 /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos
2171 /// 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.
2172 /// 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.
2173 /// </summary>
2174 /// <param name="pos"></param>
2175 /// <returns>1 if successful, 0 otherwise.</returns>
2176 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2177 {
2178 m_host.AddScriptLPS(1);
2179
2180 // BEGIN WORKAROUND
2181 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
2182 //
2183 // This workaround is to prevent silent failure of this function.
2184 // According to the specification on the SL Wiki, providing a position outside of the
2185 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
2186 {
2187 return 0;
2188 }
2189 // END WORK AROUND
2190 else if ( // this is not part of the workaround if-block because it's not related to the workaround.
2191 IsPhysical() ||
2192 m_host.ParentGroup.IsAttachment || // return FALSE if attachment
2193 (
2194 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region.
2195 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2196 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2197 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2198 pos.z > 4096 // return FALSE if altitude than 4096m
2199 )
2200 )
2201 {
2202 return 0;
2203 }
2204
2205 // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range.
2206 // 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.
2207
2208 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
2209 LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y);
2210 LandData there = World.GetLandData((float)pos.x, (float)pos.y);
2211
2212 // 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.
2213
2214 bool sameParcel = here.GlobalID == there.GlobalID;
2215
2216 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
2217 {
2218 return 0;
2219 }
2220
2221 SetPos(m_host.ParentGroup.RootPart, pos, false);
2222
2223 return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0;
2224 }
2225
2163 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2226 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
2164 // note linked setpos is capped "differently" 2227 // note linked setpos is capped "differently"
2165 private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) 2228 private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end)
@@ -2191,55 +2254,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2191 return real_vec; 2254 return real_vec;
2192 } 2255 }
2193 2256
2194 public LSL_Integer llSetRegionPos(LSL_Vector pos) 2257 /// <summary>
2195 { 2258 /// set object position, optionally capping the distance.
2196 return new LSL_Integer(SetRegionPos(m_host, pos)); 2259 /// </summary>
2197 } 2260 /// <param name="part"></param>
2198 2261 /// <param name="targetPos"></param>
2199 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos) 2262 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2200 { 2263 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2201 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2202 return 0;
2203
2204 SceneObjectGroup grp = part.ParentGroup;
2205
2206 if (grp.IsAttachment)
2207 return 0;
2208
2209 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2210 return 0;
2211
2212 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)
2213 return 0;
2214
2215 float constrainedX = (float)targetPos.x;
2216 float constrainedY = (float)targetPos.y;
2217
2218 if (constrainedX < 0.0f)
2219 constrainedX = 0.0f;
2220 if (constrainedY < 0.0f)
2221 constrainedY = 0.0f;
2222 if (constrainedX >= (float)Constants.RegionSize)
2223 constrainedX = (float)Constants.RegionSize - 0.1f;
2224 if (constrainedY >= (float)Constants.RegionSize)
2225 constrainedY = (float)Constants.RegionSize -0.1f;
2226
2227 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2228
2229 if (targetPos.z < ground)
2230 targetPos.z = ground;
2231
2232 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2233
2234 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2235 return 0;
2236
2237 grp.UpdateGroupPosition(dest);
2238
2239 return 1;
2240 }
2241
2242 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2243 { 2264 {
2244 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2245 return; 2266 return;