diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 135 |
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; |