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.cs1353
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs341
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs115
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs134
13 files changed, 1455 insertions, 743 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index adef0e6..d8da173 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -341,7 +341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
341 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
342 } 342 }
343 343
344 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
345 { 345 {
346 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -426,14 +426,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
426 return key; 426 return key;
427 } 427 }
428 428
429 // convert a LSL_Rotation to a Quaternion
430 public static Quaternion Rot2Quaternion(LSL_Rotation r)
431 {
432 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
433 q.Normalize();
434 return q;
435 }
436
437 //These are the implementations of the various ll-functions used by the LSL scripts. 429 //These are the implementations of the various ll-functions used by the LSL scripts.
438 public LSL_Float llSin(double f) 430 public LSL_Float llSin(double f)
439 { 431 {
@@ -1240,9 +1232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1240 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
1241 { 1233 {
1242 m_host.AddScriptLPS(1); 1234 m_host.AddScriptLPS(1);
1243 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 1235 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
1244 (float)offset.y,
1245 (float)offset.z);
1246 1236
1247 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 1237 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
1248 LSL_Vector vsn = llGroundNormal(offset); 1238 LSL_Vector vsn = llGroundNormal(offset);
@@ -1492,31 +1482,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 if (part == null || part.ParentGroup.IsDeleted) 1482 if (part == null || part.ParentGroup.IsDeleted)
1493 return; 1483 return;
1494 1484
1495 if (scale.x < 0.01) 1485 // First we need to check whether or not we need to clamp the size of a physics-enabled prim
1496 scale.x = 0.01;
1497 if (scale.y < 0.01)
1498 scale.y = 0.01;
1499 if (scale.z < 0.01)
1500 scale.z = 0.01;
1501
1502 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; 1486 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1503
1504 if (pa != null && pa.IsPhysical) 1487 if (pa != null && pa.IsPhysical)
1505 { 1488 {
1506 if (scale.x > World.m_maxPhys) 1489 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1507 scale.x = World.m_maxPhys; 1490 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1508 if (scale.y > World.m_maxPhys) 1491 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1509 scale.y = World.m_maxPhys; 1492 }
1510 if (scale.z > World.m_maxPhys) 1493 else
1511 scale.z = World.m_maxPhys; 1494 {
1495 // If not physical, then we clamp the scale to the non-physical min/max
1496 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1497 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1498 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1512 } 1499 }
1513
1514 if (scale.x > World.m_maxNonphys)
1515 scale.x = World.m_maxNonphys;
1516 if (scale.y > World.m_maxNonphys)
1517 scale.y = World.m_maxNonphys;
1518 if (scale.z > World.m_maxNonphys)
1519 scale.z = World.m_maxNonphys;
1520 1500
1521 Vector3 tmp = part.Scale; 1501 Vector3 tmp = part.Scale;
1522 tmp.X = (float)scale.x; 1502 tmp.X = (float)scale.x;
@@ -1590,7 +1570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1590 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1591 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1592 1572
1593 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 1573 m_host.SetFaceColorAlpha(face, color, null);
1594 } 1574 }
1595 1575
1596 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -2202,7 +2182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2202 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2182 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2203 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. 2183 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2204 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. 2184 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2205 pos.z > 4096 // return FALSE if altitude than 4096m 2185 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2206 ) 2186 )
2207 ) 2187 )
2208 { 2188 {
@@ -2213,14 +2193,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2213 // 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. 2193 // 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.
2214 2194
2215 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; 2195 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
2216 LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); 2196 LandData here = World.GetLandData(objectPos);
2217 LandData there = World.GetLandData((float)pos.x, (float)pos.y); 2197 LandData there = World.GetLandData(pos);
2218 2198
2219 // 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. 2199 // 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.
2220 2200
2221 bool sameParcel = here.GlobalID == there.GlobalID; 2201 bool sameParcel = here.GlobalID == there.GlobalID;
2222 2202
2223 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2203 if (!sameParcel && !World.Permissions.CanRezObject(
2204 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
2224 { 2205 {
2225 return 0; 2206 return 0;
2226 } 2207 }
@@ -2279,16 +2260,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2280 { 2261 {
2281 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2282 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2283 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2284 return; 2264 return;
2285 Util.FireAndForget(delegate(object x) { 2265 Util.FireAndForget(delegate(object x) {
2286 parent.UpdateGroupPosition(dest); 2266 parent.UpdateGroupPosition((Vector3)toPos);
2287 }); 2267 });
2288 } 2268 }
2289 else 2269 else
2290 { 2270 {
2291 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2271 part.OffsetPosition = (Vector3)toPos;
2292 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2293 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2294 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2326,7 +2306,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2326 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2327 } 2307 }
2328 2308
2329 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2310
2311 return new LSL_Vector(pos);
2330 } 2312 }
2331 2313
2332 public void llSetRot(LSL_Rotation rot) 2314 public void llSetRot(LSL_Rotation rot)
@@ -2334,26 +2316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2334 m_host.AddScriptLPS(1); 2316 m_host.AddScriptLPS(1);
2335 2317
2336 // try to let this work as in SL... 2318 // try to let this work as in SL...
2337 if (m_host.LinkNum < 2) 2319 if (m_host.ParentID == 0)
2338 { 2320 {
2339 // Special case: If we are root, rotate complete SOG to new 2321 // special case: If we are root, rotate complete SOG to new rotation
2340 // rotation. 2322 SetRot(m_host, rot);
2341 // We are root if the link number is 0 (single prim) or 1
2342 // (root prim). ParentID may be nonzero in attachments and
2343 // using it would cause attachments and HUDs to rotate
2344 // to the wrong positions.
2345
2346 SetRot(m_host, Rot2Quaternion(rot));
2347 } 2323 }
2348 else 2324 else
2349 { 2325 {
2350 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2326 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2351 SceneObjectPart rootPart; 2327 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2352 if (m_host.ParentGroup != null) // better safe than sorry 2328 if (rootPart != null) // better safe than sorry
2353 { 2329 {
2354 rootPart = m_host.ParentGroup.RootPart; 2330 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2355 if (rootPart != null)
2356 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2357 } 2331 }
2358 } 2332 }
2359 2333
@@ -2363,8 +2337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 public void llSetLocalRot(LSL_Rotation rot) 2337 public void llSetLocalRot(LSL_Rotation rot)
2364 { 2338 {
2365 m_host.AddScriptLPS(1); 2339 m_host.AddScriptLPS(1);
2366 2340 SetRot(m_host, rot);
2367 SetRot(m_host, Rot2Quaternion(rot));
2368 ScriptSleep(200); 2341 ScriptSleep(200);
2369 } 2342 }
2370 2343
@@ -2476,7 +2449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2476 if (local != 0) 2449 if (local != 0)
2477 force *= llGetRot(); 2450 force *= llGetRot();
2478 2451
2479 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2452 m_host.ParentGroup.RootPart.SetForce(force);
2480 } 2453 }
2481 } 2454 }
2482 2455
@@ -2488,10 +2461,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2488 2461
2489 if (!m_host.ParentGroup.IsDeleted) 2462 if (!m_host.ParentGroup.IsDeleted)
2490 { 2463 {
2491 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2464 force = m_host.ParentGroup.RootPart.GetForce();
2492 force.x = tmpForce.X;
2493 force.y = tmpForce.Y;
2494 force.z = tmpForce.Z;
2495 } 2465 }
2496 2466
2497 return force; 2467 return force;
@@ -2500,8 +2470,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 public LSL_Integer llTarget(LSL_Vector position, double range) 2470 public LSL_Integer llTarget(LSL_Vector position, double range)
2501 { 2471 {
2502 m_host.AddScriptLPS(1); 2472 m_host.AddScriptLPS(1);
2503 return m_host.ParentGroup.registerTargetWaypoint( 2473 return m_host.ParentGroup.registerTargetWaypoint(position,
2504 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2474 (float)range);
2505 } 2475 }
2506 2476
2507 public void llTargetRemove(int number) 2477 public void llTargetRemove(int number)
@@ -2513,8 +2483,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2483 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2514 { 2484 {
2515 m_host.AddScriptLPS(1); 2485 m_host.AddScriptLPS(1);
2516 return m_host.ParentGroup.registerRotTargetWaypoint( 2486 return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error);
2517 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2518 } 2487 }
2519 2488
2520 public void llRotTargetRemove(int number) 2489 public void llRotTargetRemove(int number)
@@ -2526,7 +2495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2526 public void llMoveToTarget(LSL_Vector target, double tau) 2495 public void llMoveToTarget(LSL_Vector target, double tau)
2527 { 2496 {
2528 m_host.AddScriptLPS(1); 2497 m_host.AddScriptLPS(1);
2529 m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); 2498 m_host.MoveToTarget(target, (float)tau);
2530 } 2499 }
2531 2500
2532 public void llStopMoveToTarget() 2501 public void llStopMoveToTarget()
@@ -2539,7 +2508,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2539 { 2508 {
2540 m_host.AddScriptLPS(1); 2509 m_host.AddScriptLPS(1);
2541 //No energy force yet 2510 //No energy force yet
2542 Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z); 2511 Vector3 v = force;
2543 if (v.Length() > 20000.0f) 2512 if (v.Length() > 20000.0f)
2544 { 2513 {
2545 v.Normalize(); 2514 v.Normalize();
@@ -2552,13 +2521,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2552 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2553 { 2522 {
2554 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2555 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2556 } 2525 }
2557 2526
2558 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2559 { 2528 {
2560 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2561 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2562 } 2531 }
2563 2532
2564 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -3123,13 +3092,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 return; 3092 return;
3124 } 3093 }
3125 3094
3126 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
3127 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
3128
3129 // need the magnitude later 3095 // need the magnitude later
3130 // float velmag = (float)Util.GetMagnitude(llvel); 3096 // float velmag = (float)Util.GetMagnitude(llvel);
3131 3097
3132 SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); 3098 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
3133 3099
3134 // If either of these are null, then there was an unknown error. 3100 // If either of these are null, then there was an unknown error.
3135 if (new_group == null) 3101 if (new_group == null)
@@ -3156,11 +3122,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 3122
3157 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
3158 3124
3159 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3160 { 3126 {
3161 float groupmass = new_group.GetMass(); 3127 float groupmass = new_group.GetMass();
3162 llvel *= -groupmass; 3128 vel *= -groupmass;
3163 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0); 3129 llApplyImpulse(vel, 0);
3164 } 3130 }
3165 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3166 return; 3132 return;
@@ -3211,7 +3177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3211 return; 3177 return;
3212 } 3178 }
3213 3179
3214 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); 3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3215 } 3181 }
3216 } 3182 }
3217 3183
@@ -3637,7 +3603,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 } 3603 }
3638 else 3604 else
3639 { 3605 {
3640 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); 3606 m_host.RotLookAt(target, (float)strength, (float)damping);
3641 } 3607 }
3642 } 3608 }
3643 3609
@@ -3718,7 +3684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 3684
3719 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3685 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3720 { 3686 {
3721 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3687 part.UpdateAngularVelocity(axis * spinrate);
3722 } 3688 }
3723 3689
3724 public LSL_Integer llGetStartParameter() 3690 public LSL_Integer llGetStartParameter()
@@ -3928,7 +3894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3928 try 3894 try
3929 { 3895 {
3930 foreach (SceneObjectPart part in parts) 3896 foreach (SceneObjectPart part in parts)
3931 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3897 part.SetFaceColorAlpha(face, color, null);
3932 } 3898 }
3933 finally 3899 finally
3934 { 3900 {
@@ -4398,9 +4364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4398 public void llSetText(string text, LSL_Vector color, double alpha) 4364 public void llSetText(string text, LSL_Vector color, double alpha)
4399 { 4365 {
4400 m_host.AddScriptLPS(1); 4366 m_host.AddScriptLPS(1);
4401 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4367 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4402 Util.Clip((float)color.y, 0.0f, 1.0f),
4403 Util.Clip((float)color.z, 0.0f, 1.0f));
4404 if (text.Length > 254) 4368 if (text.Length > 254)
4405 text = text.Remove(254); 4369 text = text.Remove(254);
4406 4370
@@ -4627,14 +4591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4627 ScriptSleep(5000); 4591 ScriptSleep(5000);
4628 } 4592 }
4629 4593
4630 public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) 4594 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4631 { 4595 {
4632 m_host.AddScriptLPS(1); 4596 m_host.AddScriptLPS(1);
4633 UUID agentId = new UUID(); 4597 UUID agentId = new UUID();
4634 4598
4635 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4636 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4637
4638 if (UUID.TryParse(agent, out agentId)) 4599 if (UUID.TryParse(agent, out agentId))
4639 { 4600 {
4640 ScenePresence presence = World.GetScenePresence(agentId); 4601 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4663,15 +4624,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4663 } 4624 }
4664 } 4625 }
4665 4626
4666 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) 4627 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4667 { 4628 {
4668 m_host.AddScriptLPS(1); 4629 m_host.AddScriptLPS(1);
4669 UUID agentId = new UUID(); 4630 UUID agentId = new UUID();
4670 4631
4671 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4632 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
4672 4633
4673 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4674 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4675 if (UUID.TryParse(agent, out agentId)) 4634 if (UUID.TryParse(agent, out agentId))
4676 { 4635 {
4677 ScenePresence presence = World.GetScenePresence(agentId); 4636 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4968,7 +4927,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4968 distance_attenuation = 1f / normalized_units; 4927 distance_attenuation = 1f / normalized_units;
4969 } 4928 }
4970 4929
4971 Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); 4930 Vector3 applied_linear_impulse = impulse;
4972 { 4931 {
4973 float impulse_length = applied_linear_impulse.Length(); 4932 float impulse_length = applied_linear_impulse.Length();
4974 4933
@@ -5616,25 +5575,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5616 /// separated list. There is a space after 5575 /// separated list. There is a space after
5617 /// each comma. 5576 /// each comma.
5618 /// </summary> 5577 /// </summary>
5619
5620 public LSL_String llList2CSV(LSL_List src) 5578 public LSL_String llList2CSV(LSL_List src)
5621 { 5579 {
5622
5623 string ret = String.Empty;
5624 int x = 0;
5625
5626 m_host.AddScriptLPS(1); 5580 m_host.AddScriptLPS(1);
5627 5581
5628 if (src.Data.Length > 0) 5582 return string.Join(", ",
5629 { 5583 (new List<object>(src.Data)).ConvertAll<string>(o =>
5630 ret = src.Data[x++].ToString(); 5584 {
5631 for (; x < src.Data.Length; x++) 5585 return o.ToString();
5632 { 5586 }).ToArray());
5633 ret += ", "+src.Data[x].ToString();
5634 }
5635 }
5636
5637 return ret;
5638 } 5587 }
5639 5588
5640 /// <summary> 5589 /// <summary>
@@ -5933,27 +5882,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5933 /// Returns the index of the first occurrence of test 5882 /// Returns the index of the first occurrence of test
5934 /// in src. 5883 /// in src.
5935 /// </summary> 5884 /// </summary>
5936 5885 /// <param name="src">Source list</param>
5886 /// <param name="test">List to search for</param>
5887 /// <returns>
5888 /// The index number of the point in src where test was found if it was found.
5889 /// Otherwise returns -1
5890 /// </returns>
5937 public LSL_Integer llListFindList(LSL_List src, LSL_List test) 5891 public LSL_Integer llListFindList(LSL_List src, LSL_List test)
5938 { 5892 {
5939
5940 int index = -1; 5893 int index = -1;
5941 int length = src.Length - test.Length + 1; 5894 int length = src.Length - test.Length + 1;
5942 5895
5943 m_host.AddScriptLPS(1); 5896 m_host.AddScriptLPS(1);
5944 5897
5945 // If either list is empty, do not match 5898 // If either list is empty, do not match
5946
5947 if (src.Length != 0 && test.Length != 0) 5899 if (src.Length != 0 && test.Length != 0)
5948 { 5900 {
5949 for (int i = 0; i < length; i++) 5901 for (int i = 0; i < length; i++)
5950 { 5902 {
5951 if (src.Data[i].Equals(test.Data[0])) 5903 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
5904 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
5905 // and so the comparison fails even if the LSL_Integer conceptually has the same value.
5906 // Therefore, here we test Equals on both the source and destination objects.
5907 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5908 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))
5952 { 5909 {
5953 int j; 5910 int j;
5954 for (j = 1; j < test.Length; j++) 5911 for (j = 1; j < test.Length; j++)
5955 if (!src.Data[i+j].Equals(test.Data[j])) 5912 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))
5956 break; 5913 break;
5914
5957 if (j == test.Length) 5915 if (j == test.Length)
5958 { 5916 {
5959 index = i; 5917 index = i;
@@ -5964,19 +5922,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5964 } 5922 }
5965 5923
5966 return index; 5924 return index;
5967
5968 } 5925 }
5969 5926
5970 public LSL_String llGetObjectName() 5927 public LSL_String llGetObjectName()
5971 { 5928 {
5972 m_host.AddScriptLPS(1); 5929 m_host.AddScriptLPS(1);
5973 return m_host.Name!=null?m_host.Name:String.Empty; 5930 return m_host.Name !=null ? m_host.Name : String.Empty;
5974 } 5931 }
5975 5932
5976 public void llSetObjectName(string name) 5933 public void llSetObjectName(string name)
5977 { 5934 {
5978 m_host.AddScriptLPS(1); 5935 m_host.AddScriptLPS(1);
5979 m_host.Name = name!=null?name:String.Empty; 5936 m_host.Name = name != null ? name : String.Empty;
5980 } 5937 }
5981 5938
5982 public LSL_String llGetDate() 5939 public LSL_String llGetDate()
@@ -6307,19 +6264,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6307 m_host.AddScriptLPS(1); 6264 m_host.AddScriptLPS(1);
6308 6265
6309 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6266 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6310 if (parts.Count > 0) 6267
6268 try
6311 { 6269 {
6312 try 6270 foreach (SceneObjectPart part in parts)
6313 {
6314 foreach (var part in parts)
6315 {
6316 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6317 }
6318 }
6319 finally
6320 { 6271 {
6272 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6321 } 6273 }
6322 } 6274 }
6275 finally
6276 {
6277 }
6323 } 6278 }
6324 6279
6325 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 6280 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
@@ -6537,9 +6492,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6537 6492
6538 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6493 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6539 //the height of that point on the plane. The resulting vector gives the slope. 6494 //the height of that point on the plane. The resulting vector gives the slope.
6540 Vector3 vsl = new Vector3(); 6495 Vector3 vsl = vsn;
6541 vsl.X = (float)vsn.x;
6542 vsl.Y = (float)vsn.y;
6543 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6496 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6544 vsl.Normalize(); 6497 vsl.Normalize();
6545 //Normalization might be overkill here 6498 //Normalization might be overkill here
@@ -6550,9 +6503,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6550 public LSL_Vector llGroundNormal(LSL_Vector offset) 6503 public LSL_Vector llGroundNormal(LSL_Vector offset)
6551 { 6504 {
6552 m_host.AddScriptLPS(1); 6505 m_host.AddScriptLPS(1);
6553 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 6506 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6554 (float)offset.y,
6555 (float)offset.z);
6556 // Clamp to valid position 6507 // Clamp to valid position
6557 if (pos.X < 0) 6508 if (pos.X < 0)
6558 pos.X = 0; 6509 pos.X = 0;
@@ -6717,7 +6668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6717 6668
6718 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6669 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6719 6670
6720 foreach (var part in parts) 6671 foreach (SceneObjectPart part in parts)
6721 { 6672 {
6722 SetParticleSystem(part, rules); 6673 SetParticleSystem(part, rules);
6723 } 6674 }
@@ -7006,8 +6957,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7006 6957
7007 if (!m_host.ParentGroup.IsDeleted) 6958 if (!m_host.ParentGroup.IsDeleted)
7008 { 6959 {
7009 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, 6960 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
7010 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
7011 } 6961 }
7012 } 6962 }
7013 6963
@@ -7019,7 +6969,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7019 6969
7020 if (!m_host.ParentGroup.IsDeleted) 6970 if (!m_host.ParentGroup.IsDeleted)
7021 { 6971 {
7022 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); 6972 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
7023 } 6973 }
7024 } 6974 }
7025 6975
@@ -7049,8 +6999,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7049 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6999 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7050 rot.s = 1; // ZERO_ROTATION = 0,0,0,1 7000 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7051 7001
7052 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 7002 part.SitTargetPosition = offset;
7053 part.SitTargetOrientation = Rot2Quaternion(rot); 7003 part.SitTargetOrientation = rot;
7054 part.ParentGroup.HasGroupChanged = true; 7004 part.ParentGroup.HasGroupChanged = true;
7055 } 7005 }
7056 7006
@@ -7153,13 +7103,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7153 public void llSetCameraEyeOffset(LSL_Vector offset) 7103 public void llSetCameraEyeOffset(LSL_Vector offset)
7154 { 7104 {
7155 m_host.AddScriptLPS(1); 7105 m_host.AddScriptLPS(1);
7156 m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7106 m_host.SetCameraEyeOffset(offset);
7157 } 7107 }
7158 7108
7159 public void llSetCameraAtOffset(LSL_Vector offset) 7109 public void llSetCameraAtOffset(LSL_Vector offset)
7160 { 7110 {
7161 m_host.AddScriptLPS(1); 7111 m_host.AddScriptLPS(1);
7162 m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7112 m_host.SetCameraAtOffset(offset);
7163 } 7113 }
7164 7114
7165 public LSL_String llDumpList2String(LSL_List src, string seperator) 7115 public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -7181,7 +7131,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7181 public LSL_Integer llScriptDanger(LSL_Vector pos) 7131 public LSL_Integer llScriptDanger(LSL_Vector pos)
7182 { 7132 {
7183 m_host.AddScriptLPS(1); 7133 m_host.AddScriptLPS(1);
7184 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); 7134 bool result = World.ScriptDanger(m_host.LocalId, pos);
7185 if (result) 7135 if (result)
7186 { 7136 {
7187 return 1; 7137 return 1;
@@ -7763,7 +7713,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7763 { 7713 {
7764 m_host.AddScriptLPS(1); 7714 m_host.AddScriptLPS(1);
7765 7715
7766 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7716 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7767 7717
7768 ScriptSleep(200); 7718 ScriptSleep(200);
7769 } 7719 }
@@ -7772,10 +7722,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7772 { 7722 {
7773 m_host.AddScriptLPS(1); 7723 m_host.AddScriptLPS(1);
7774 7724
7775 setLinkPrimParams(linknumber, rules); 7725 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7726
7727 ScriptSleep(200);
7776 } 7728 }
7777 7729
7778 private void setLinkPrimParams(int linknumber, LSL_List rules) 7730 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7779 { 7731 {
7780 List<object> parts = new List<object>(); 7732 List<object> parts = new List<object>();
7781 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7733 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7786,15 +7738,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7786 parts.Add(p); 7738 parts.Add(p);
7787 7739
7788 LSL_List remaining = null; 7740 LSL_List remaining = null;
7741 uint rulesParsed = 0;
7789 7742
7790 if (parts.Count > 0) 7743 if (parts.Count > 0)
7791 { 7744 {
7792 foreach (object part in parts) 7745 foreach (object part in parts)
7793 { 7746 {
7794 if (part is SceneObjectPart) 7747 if (part is SceneObjectPart)
7795 remaining = SetPrimParams((SceneObjectPart)part, rules); 7748 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7796 else 7749 else
7797 remaining = SetPrimParams((ScenePresence)part, rules); 7750 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7798 } 7751 }
7799 7752
7800 while ((object)remaining != null && remaining.Length > 2) 7753 while ((object)remaining != null && remaining.Length > 2)
@@ -7813,9 +7766,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7813 foreach (object part in parts) 7766 foreach (object part in parts)
7814 { 7767 {
7815 if (part is SceneObjectPart) 7768 if (part is SceneObjectPart)
7816 remaining = SetPrimParams((SceneObjectPart)part, rules); 7769 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7817 else 7770 else
7818 remaining = SetPrimParams((ScenePresence)part, rules); 7771 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7819 } 7772 }
7820 } 7773 }
7821 } 7774 }
@@ -7853,6 +7806,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7853 7806
7854 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7807 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7855 { 7808 {
7809 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7856 llSetLinkPrimitiveParamsFast(linknumber, rules); 7810 llSetLinkPrimitiveParamsFast(linknumber, rules);
7857 ScriptSleep(200); 7811 ScriptSleep(200);
7858 } 7812 }
@@ -7880,195 +7834,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7880 return new Vector3((float)x, (float)y, (float)z); 7834 return new Vector3((float)x, (float)y, (float)z);
7881 } 7835 }
7882 7836
7883 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 7837 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7884 {
7885 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7886
7887 int idx = 0;
7888
7889 bool positionChanged = false;
7890 Vector3 finalPos = Vector3.Zero;
7891
7892 try
7893 {
7894 while (idx < rules.Length)
7895 {
7896 int code = rules.GetLSLIntegerItem(idx++);
7897
7898 int remain = rules.Length - idx;
7899
7900 switch (code)
7901 {
7902 case (int)ScriptBaseClass.PRIM_POSITION:
7903 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7904 {
7905 if (remain < 1)
7906 return null;
7907
7908 LSL_Vector v;
7909 v = rules.GetVector3Item(idx++);
7910
7911 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7912 if (part == null)
7913 break;
7914
7915 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7916 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7917 if (part.LinkNum > 1)
7918 {
7919 localRot = GetPartLocalRot(part);
7920 localPos = GetPartLocalPos(part);
7921 }
7922
7923 v -= localPos;
7924 v /= localRot;
7925
7926 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7927
7928 v = v + 2 * sitOffset;
7929
7930 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7931 av.SendAvatarDataToAllAgents();
7932
7933 }
7934 break;
7935
7936 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7937 case (int)ScriptBaseClass.PRIM_ROTATION:
7938 {
7939 if (remain < 1)
7940 return null;
7941
7942 LSL_Rotation r;
7943 r = rules.GetQuaternionItem(idx++);
7944
7945 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7946 if (part == null)
7947 break;
7948
7949 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7950 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7951
7952 if (part.LinkNum > 1)
7953 localRot = GetPartLocalRot(part);
7954
7955 r = r * llGetRootRotation() / localRot;
7956 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7957 av.SendAvatarDataToAllAgents();
7958 }
7959 break;
7960
7961 // parse rest doing nothing but number of parameters error check
7962 case (int)ScriptBaseClass.PRIM_SIZE:
7963 case (int)ScriptBaseClass.PRIM_MATERIAL:
7964 case (int)ScriptBaseClass.PRIM_PHANTOM:
7965 case (int)ScriptBaseClass.PRIM_PHYSICS:
7966 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7967 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7968 case (int)ScriptBaseClass.PRIM_NAME:
7969 case (int)ScriptBaseClass.PRIM_DESC:
7970 if (remain < 1)
7971 return null;
7972 idx++;
7973 break;
7974
7975 case (int)ScriptBaseClass.PRIM_GLOW:
7976 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7977 case (int)ScriptBaseClass.PRIM_TEXGEN:
7978 if (remain < 2)
7979 return null;
7980 idx += 2;
7981 break;
7982
7983 case (int)ScriptBaseClass.PRIM_TYPE:
7984 if (remain < 3)
7985 return null;
7986 code = (int)rules.GetLSLIntegerItem(idx++);
7987 remain = rules.Length - idx;
7988 switch (code)
7989 {
7990 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7991 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7992 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7993 if (remain < 6)
7994 return null;
7995 idx += 6;
7996 break;
7997
7998 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7999 if (remain < 5)
8000 return null;
8001 idx += 5;
8002 break;
8003
8004 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
8005 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
8006 case (int)ScriptBaseClass.PRIM_TYPE_RING:
8007 if (remain < 11)
8008 return null;
8009 idx += 11;
8010 break;
8011
8012 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
8013 if (remain < 2)
8014 return null;
8015 idx += 2;
8016 break;
8017 }
8018 break;
8019
8020 case (int)ScriptBaseClass.PRIM_COLOR:
8021 case (int)ScriptBaseClass.PRIM_TEXT:
8022 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8023 case (int)ScriptBaseClass.PRIM_OMEGA:
8024 if (remain < 3)
8025 return null;
8026 idx += 3;
8027 break;
8028
8029 case (int)ScriptBaseClass.PRIM_TEXTURE:
8030 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8031 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8032 if (remain < 5)
8033 return null;
8034 idx += 5;
8035 break;
8036
8037 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8038 if (remain < 7)
8039 return null;
8040
8041 idx += 7;
8042 break;
8043
8044 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8045 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8046 return null;
8047
8048 return rules.GetSublist(idx, -1);
8049 }
8050 }
8051 }
8052
8053 finally
8054 {
8055 if (positionChanged)
8056 {
8057 av.OffsetPosition = finalPos;
8058// av.SendAvatarDataToAllAgents();
8059 av.SendTerseUpdateToAllClients();
8060 positionChanged = false;
8061 }
8062 }
8063 return null;
8064 }
8065
8066 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
8067 { 7838 {
8068 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7839 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8069 return null; 7840 return null;
8070 7841
8071 int idx = 0; 7842 int idx = 0;
7843 int idxStart = 0;
8072 7844
8073 SceneObjectGroup parentgrp = part.ParentGroup; 7845 SceneObjectGroup parentgrp = part.ParentGroup;
8074 7846
@@ -8079,9 +7851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8079 { 7851 {
8080 while (idx < rules.Length) 7852 while (idx < rules.Length)
8081 { 7853 {
7854 ++rulesParsed;
8082 int code = rules.GetLSLIntegerItem(idx++); 7855 int code = rules.GetLSLIntegerItem(idx++);
8083 7856
8084 int remain = rules.Length - idx; 7857 int remain = rules.Length - idx;
7858 idxStart = idx;
8085 7859
8086 int face; 7860 int face;
8087 LSL_Vector v; 7861 LSL_Vector v;
@@ -8111,18 +7885,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8111 return null; 7885 return null;
8112 7886
8113 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7887 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8114 SceneObjectPart rootPart = parentgrp.RootPart;
8115 // try to let this work as in SL... 7888 // try to let this work as in SL...
8116 if (rootPart == part) 7889 if (part.ParentID == 0)
8117 { 7890 {
8118 // special case: If we are root, rotate complete SOG to new rotation 7891 // special case: If we are root, rotate complete SOG to new rotation
8119 SetRot(part, Rot2Quaternion(q)); 7892 SetRot(part, q);
8120 } 7893 }
8121 else 7894 else
8122 { 7895 {
8123 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7896 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
8124 // sounds like sl bug that we need to replicate 7897 SceneObjectPart rootPart = part.ParentGroup.RootPart;
8125 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7898 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
8126 } 7899 }
8127 7900
8128 break; 7901 break;
@@ -8296,8 +8069,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8296 LSL_Vector color=rules.GetVector3Item(idx++); 8069 LSL_Vector color=rules.GetVector3Item(idx++);
8297 double alpha=(double)rules.GetLSLFloatItem(idx++); 8070 double alpha=(double)rules.GetLSLFloatItem(idx++);
8298 8071
8299 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 8072 part.SetFaceColorAlpha(face, color, alpha);
8300 SetAlpha(part, alpha, face);
8301 8073
8302 break; 8074 break;
8303 8075
@@ -8445,9 +8217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8445 string primText = rules.GetLSLStringItem(idx++); 8217 string primText = rules.GetLSLStringItem(idx++);
8446 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 8218 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
8447 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 8219 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
8448 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 8220 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
8449 Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
8450 Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
8451 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 8221 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
8452 8222
8453 break; 8223 break;
@@ -8466,8 +8236,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8466 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8236 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8467 if (remain < 1) 8237 if (remain < 1)
8468 return null; 8238 return null;
8469 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8239 SetRot(part, rules.GetQuaternionItem(idx++));
8470 SetRot(part, Rot2Quaternion(lr));
8471 break; 8240 break;
8472 case (int)ScriptBaseClass.PRIM_OMEGA: 8241 case (int)ScriptBaseClass.PRIM_OMEGA:
8473 if (remain < 3) 8242 if (remain < 3)
@@ -8477,7 +8246,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8477 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8246 LSL_Float gain = rules.GetLSLFloatItem(idx++);
8478 TargetOmega(part, axis, (double)spinrate, (double)gain); 8247 TargetOmega(part, axis, (double)spinrate, (double)gain);
8479 break; 8248 break;
8480 8249 case (int)ScriptBaseClass.PRIM_SLICE:
8250 if (remain < 1)
8251 return null;
8252 LSL_Vector slice = rules.GetVector3Item(idx++);
8253 part.UpdateSlice((float)slice.x, (float)slice.y);
8254 break;
8481 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8255 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8482 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8256 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8483 return null; 8257 return null;
@@ -8486,6 +8260,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8486 } 8260 }
8487 } 8261 }
8488 } 8262 }
8263 catch (InvalidCastException e)
8264 {
8265 ShoutError(string.Format(
8266 "{0} error running rule #{1}: arg #{2} ",
8267 originFunc, rulesParsed, idx - idxStart) + e.Message);
8268 }
8489 finally 8269 finally
8490 { 8270 {
8491 if (positionChanged) 8271 if (positionChanged)
@@ -8494,12 +8274,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8494 { 8274 {
8495 SceneObjectGroup parent = part.ParentGroup; 8275 SceneObjectGroup parent = part.ParentGroup;
8496 Util.FireAndForget(delegate(object x) { 8276 Util.FireAndForget(delegate(object x) {
8497 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8277 parent.UpdateGroupPosition(currentPosition);
8498 }); 8278 });
8499 } 8279 }
8500 else 8280 else
8501 { 8281 {
8502 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); 8282 part.OffsetPosition = currentPosition;
8503 SceneObjectGroup parent = part.ParentGroup; 8283 SceneObjectGroup parent = part.ParentGroup;
8504 parent.HasGroupChanged = true; 8284 parent.HasGroupChanged = true;
8505 parent.ScheduleGroupForTerseUpdate(); 8285 parent.ScheduleGroupForTerseUpdate();
@@ -8877,7 +8657,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8877 public LSL_List llGetPrimitiveParams(LSL_List rules) 8657 public LSL_List llGetPrimitiveParams(LSL_List rules)
8878 { 8658 {
8879 m_host.AddScriptLPS(1); 8659 m_host.AddScriptLPS(1);
8880 return GetLinkPrimitiveParams(m_host, rules); 8660
8661 LSL_List result = new LSL_List();
8662
8663 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8664
8665 while (remaining != null && remaining.Length > 2)
8666 {
8667 int linknumber = remaining.GetLSLIntegerItem(0);
8668 rules = remaining.GetSublist(1, -1);
8669 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8670
8671 foreach (SceneObjectPart part in parts)
8672 remaining = GetPrimParams(part, rules, ref result);
8673 }
8674
8675 return result;
8881 } 8676 }
8882 8677
8883 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8678 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -8887,294 +8682,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8887 // acording to SL wiki this must indicate a single link number or link_root or link_this. 8682 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8888 // keep other options as before 8683 // keep other options as before
8889 8684
8890 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8685 List<SceneObjectPart> parts;
8891 List<ScenePresence> avatars = GetLinkAvatars(linknumber); 8686 List<ScenePresence> avatars;
8892 8687
8893 LSL_List res = new LSL_List(); 8688 LSL_List res = new LSL_List();
8689 LSL_List remaining = null;
8894 8690
8895 if (parts.Count > 0) 8691 while (rules.Length > 0)
8896 { 8692 {
8897 foreach (var part in parts) 8693 parts = GetLinkParts(linknumber);
8694 avatars = GetLinkAvatars(linknumber);
8695
8696 remaining = null;
8697 foreach (SceneObjectPart part in parts)
8898 { 8698 {
8899 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8699 remaining = GetPrimParams(part, rules, ref res);
8900 res += partRes;
8901 } 8700 }
8902 }
8903 if (avatars.Count > 0)
8904 {
8905 foreach (ScenePresence avatar in avatars) 8701 foreach (ScenePresence avatar in avatars)
8906 { 8702 {
8907 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules); 8703 remaining = GetPrimParams(avatar, rules, ref res);
8908 res += avaRes;
8909 } 8704 }
8910 }
8911 return res;
8912 }
8913 8705
8914 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules) 8706 if (remaining != null && remaining.Length > 0)
8915 {
8916 // avatars case
8917 // replies as SL wiki
8918
8919 LSL_List res = new LSL_List();
8920// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8921 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8922
8923 int idx = 0;
8924 while (idx < rules.Length)
8925 {
8926 int code = (int)rules.GetLSLIntegerItem(idx++);
8927 int remain = rules.Length - idx;
8928
8929 switch (code)
8930 { 8707 {
8931 case (int)ScriptBaseClass.PRIM_MATERIAL: 8708 linknumber = remaining.GetLSLIntegerItem(0);
8932 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); 8709 rules = remaining.GetSublist(1, -1);
8933 break;
8934
8935 case (int)ScriptBaseClass.PRIM_PHYSICS:
8936 res.Add(new LSL_Integer(0));
8937 break;
8938
8939 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8940 res.Add(new LSL_Integer(0));
8941 break;
8942
8943 case (int)ScriptBaseClass.PRIM_PHANTOM:
8944 res.Add(new LSL_Integer(0));
8945 break;
8946
8947 case (int)ScriptBaseClass.PRIM_POSITION:
8948
8949 Vector3 pos = avatar.OffsetPosition;
8950
8951 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8952 pos -= sitOffset;
8953
8954 if( sitPart != null)
8955 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8956
8957 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8958 break;
8959
8960 case (int)ScriptBaseClass.PRIM_SIZE:
8961 // as in llGetAgentSize above
8962 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8963 break;
8964
8965 case (int)ScriptBaseClass.PRIM_ROTATION:
8966 Quaternion rot = avatar.Rotation;
8967 if (sitPart != null)
8968 {
8969 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8970 }
8971
8972 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8973 break;
8974
8975 case (int)ScriptBaseClass.PRIM_TYPE:
8976 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8977 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8978 res.Add(new LSL_Vector(0f,1.0f,0f));
8979 res.Add(new LSL_Float(0.0f));
8980 res.Add(new LSL_Vector(0, 0, 0));
8981 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8982 res.Add(new LSL_Vector(0, 0, 0));
8983 break;
8984
8985 case (int)ScriptBaseClass.PRIM_TEXTURE:
8986 if (remain < 1)
8987 return res;
8988
8989 int face = (int)rules.GetLSLIntegerItem(idx++);
8990 if (face == ScriptBaseClass.ALL_SIDES)
8991 {
8992 for (face = 0; face < 21; face++)
8993 {
8994 res.Add(new LSL_String(""));
8995 res.Add(new LSL_Vector(0,0,0));
8996 res.Add(new LSL_Vector(0,0,0));
8997 res.Add(new LSL_Float(0.0));
8998 }
8999 }
9000 else
9001 {
9002 if (face >= 0 && face < 21)
9003 {
9004 res.Add(new LSL_String(""));
9005 res.Add(new LSL_Vector(0,0,0));
9006 res.Add(new LSL_Vector(0,0,0));
9007 res.Add(new LSL_Float(0.0));
9008 }
9009 }
9010 break;
9011
9012 case (int)ScriptBaseClass.PRIM_COLOR:
9013 if (remain < 1)
9014 return res;
9015
9016 face = (int)rules.GetLSLIntegerItem(idx++);
9017
9018 if (face == ScriptBaseClass.ALL_SIDES)
9019 {
9020 for (face = 0; face < 21; face++)
9021 {
9022 res.Add(new LSL_Vector(0,0,0));
9023 res.Add(new LSL_Float(0));
9024 }
9025 }
9026 else
9027 {
9028 res.Add(new LSL_Vector(0,0,0));
9029 res.Add(new LSL_Float(0));
9030 }
9031 break;
9032
9033 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9034 if (remain < 1)
9035 return res;
9036 face = (int)rules.GetLSLIntegerItem(idx++);
9037
9038 if (face == ScriptBaseClass.ALL_SIDES)
9039 {
9040 for (face = 0; face < 21; face++)
9041 {
9042 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9043 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9044 }
9045 }
9046 else
9047 {
9048 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9049 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9050 }
9051 break;
9052
9053 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9054 if (remain < 1)
9055 return res;
9056 face = (int)rules.GetLSLIntegerItem(idx++);
9057
9058 if (face == ScriptBaseClass.ALL_SIDES)
9059 {
9060 for (face = 0; face < 21; face++)
9061 {
9062 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9063 }
9064 }
9065 else
9066 {
9067 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9068 }
9069 break;
9070
9071 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9072 res.Add(new LSL_Integer(0));
9073 res.Add(new LSL_Integer(0));// softness
9074 res.Add(new LSL_Float(0.0f)); // gravity
9075 res.Add(new LSL_Float(0.0f)); // friction
9076 res.Add(new LSL_Float(0.0f)); // wind
9077 res.Add(new LSL_Float(0.0f)); // tension
9078 res.Add(new LSL_Vector(0f,0f,0f));
9079 break;
9080
9081 case (int)ScriptBaseClass.PRIM_TEXGEN:
9082 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9083 if (remain < 1)
9084 return res;
9085 face = (int)rules.GetLSLIntegerItem(idx++);
9086
9087 if (face == ScriptBaseClass.ALL_SIDES)
9088 {
9089 for (face = 0; face < 21; face++)
9090 {
9091 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9092 }
9093 }
9094 else
9095 {
9096 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9097 }
9098 break;
9099
9100 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9101 res.Add(new LSL_Integer(0));
9102 res.Add(new LSL_Vector(0f,0f,0f));
9103 res.Add(new LSL_Float(0f)); // intensity
9104 res.Add(new LSL_Float(0f)); // radius
9105 res.Add(new LSL_Float(0f)); // falloff
9106 break;
9107
9108 case (int)ScriptBaseClass.PRIM_GLOW:
9109 if (remain < 1)
9110 return res;
9111 face = (int)rules.GetLSLIntegerItem(idx++);
9112
9113 if (face == ScriptBaseClass.ALL_SIDES)
9114 {
9115 for (face = 0; face < 21; face++)
9116 {
9117 res.Add(new LSL_Float(0f));
9118 }
9119 }
9120 else
9121 {
9122 res.Add(new LSL_Float(0f));
9123 }
9124 break;
9125
9126 case (int)ScriptBaseClass.PRIM_TEXT:
9127 res.Add(new LSL_String(""));
9128 res.Add(new LSL_Vector(0f,0f,0f));
9129 res.Add(new LSL_Float(1.0f));
9130 break;
9131
9132 case (int)ScriptBaseClass.PRIM_NAME:
9133 res.Add(new LSL_String(avatar.Name));
9134 break;
9135
9136 case (int)ScriptBaseClass.PRIM_DESC:
9137 res.Add(new LSL_String(""));
9138 break;
9139
9140 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9141 Quaternion lrot = avatar.Rotation;
9142
9143 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9144 {
9145 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9146 }
9147 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9148 break;
9149
9150 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9151 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9152 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9153 lpos -= lsitOffset;
9154
9155 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9156 {
9157 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9158 }
9159 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9160 break;
9161
9162 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9163 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9164 return res;
9165 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9166 LSL_List new_rules = rules.GetSublist(idx, -1);
9167
9168 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9169 return res;
9170 } 8710 }
9171 } 8711 }
8712
9172 return res; 8713 return res;
9173 } 8714 }
9174 8715
9175 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 8716 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
9176 { 8717 {
9177 LSL_List res = new LSL_List();
9178 int idx=0; 8718 int idx=0;
9179 while (idx < rules.Length) 8719 while (idx < rules.Length)
9180 { 8720 {
@@ -9312,7 +8852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9312 8852
9313 case (int)ScriptBaseClass.PRIM_TEXTURE: 8853 case (int)ScriptBaseClass.PRIM_TEXTURE:
9314 if (remain < 1) 8854 if (remain < 1)
9315 return res; 8855 return null;
9316 8856
9317 int face = (int)rules.GetLSLIntegerItem(idx++); 8857 int face = (int)rules.GetLSLIntegerItem(idx++);
9318 Primitive.TextureEntry tex = part.Shape.Textures; 8858 Primitive.TextureEntry tex = part.Shape.Textures;
@@ -9352,7 +8892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9352 8892
9353 case (int)ScriptBaseClass.PRIM_COLOR: 8893 case (int)ScriptBaseClass.PRIM_COLOR:
9354 if (remain < 1) 8894 if (remain < 1)
9355 return res; 8895 return null;
9356 8896
9357 face=(int)rules.GetLSLIntegerItem(idx++); 8897 face=(int)rules.GetLSLIntegerItem(idx++);
9358 8898
@@ -9381,7 +8921,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9381 8921
9382 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8922 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9383 if (remain < 1) 8923 if (remain < 1)
9384 return res; 8924 return null;
8925
9385 face = (int)rules.GetLSLIntegerItem(idx++); 8926 face = (int)rules.GetLSLIntegerItem(idx++);
9386 8927
9387 tex = part.Shape.Textures; 8928 tex = part.Shape.Textures;
@@ -9437,7 +8978,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 8978
9438 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8979 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9439 if (remain < 1) 8980 if (remain < 1)
9440 return res; 8981 return null;
8982
9441 face = (int)rules.GetLSLIntegerItem(idx++); 8983 face = (int)rules.GetLSLIntegerItem(idx++);
9442 8984
9443 tex = part.Shape.Textures; 8985 tex = part.Shape.Textures;
@@ -9491,7 +9033,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9491 case (int)ScriptBaseClass.PRIM_TEXGEN: 9033 case (int)ScriptBaseClass.PRIM_TEXGEN:
9492 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 9034 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9493 if (remain < 1) 9035 if (remain < 1)
9494 return res; 9036 return null;
9037
9495 face = (int)rules.GetLSLIntegerItem(idx++); 9038 face = (int)rules.GetLSLIntegerItem(idx++);
9496 9039
9497 tex = part.Shape.Textures; 9040 tex = part.Shape.Textures;
@@ -9539,7 +9082,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9539 9082
9540 case (int)ScriptBaseClass.PRIM_GLOW: 9083 case (int)ScriptBaseClass.PRIM_GLOW:
9541 if (remain < 1) 9084 if (remain < 1)
9542 return res; 9085 return null;
9086
9543 face = (int)rules.GetLSLIntegerItem(idx++); 9087 face = (int)rules.GetLSLIntegerItem(idx++);
9544 9088
9545 tex = part.Shape.Textures; 9089 tex = part.Shape.Textures;
@@ -9583,18 +9127,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9583 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9127 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9584 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9128 res.Add(new LSL_Vector(GetPartLocalPos(part)));
9585 break; 9129 break;
9586 9130 case (int)ScriptBaseClass.PRIM_SLICE:
9131 PrimType prim_type = part.GetPrimType();
9132 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
9133 res.Add(new LSL_Vector(
9134 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
9135 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
9136 0
9137 ));
9138 break;
9587 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9139 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9588 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 9140 if(remain < 3)
9589 return res; 9141 return null;
9590 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 9142
9591 LSL_List new_rules = rules.GetSublist(idx, -1); 9143 return rules.GetSublist(idx, -1);
9592 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9593 res += tres;
9594 return res;
9595 } 9144 }
9596 } 9145 }
9597 return res; 9146
9147 return null;
9598 } 9148 }
9599 9149
9600 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 9150 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -10988,20 +10538,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10988 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) 10538 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10989 { 10539 {
10990 case ParcelMediaCommandEnum.Url: 10540 case ParcelMediaCommandEnum.Url:
10991 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10541 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10992 break; 10542 break;
10993 case ParcelMediaCommandEnum.Desc: 10543 case ParcelMediaCommandEnum.Desc:
10994 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).Description)); 10544 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10995 break; 10545 break;
10996 case ParcelMediaCommandEnum.Texture: 10546 case ParcelMediaCommandEnum.Texture:
10997 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaID.ToString())); 10547 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
10998 break; 10548 break;
10999 case ParcelMediaCommandEnum.Type: 10549 case ParcelMediaCommandEnum.Type:
11000 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 10550 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
11001 break; 10551 break;
11002 case ParcelMediaCommandEnum.Size: 10552 case ParcelMediaCommandEnum.Size:
11003 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth)); 10553 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth));
11004 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight)); 10554 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
11005 break; 10555 break;
11006 default: 10556 default:
11007 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10557 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
@@ -11171,9 +10721,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11171 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10721 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
11172 if (avatar != null) 10722 if (avatar != null)
11173 { 10723 {
11174 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, 10724 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
11175 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10725 simname, pos, lookAt);
11176 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
11177 } 10726 }
11178 10727
11179 ScriptSleep(1000); 10728 ScriptSleep(1000);
@@ -11358,31 +10907,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11358 public LSL_Float llListStatistics(int operation, LSL_List src) 10907 public LSL_Float llListStatistics(int operation, LSL_List src)
11359 { 10908 {
11360 m_host.AddScriptLPS(1); 10909 m_host.AddScriptLPS(1);
11361 LSL_List nums = LSL_List.ToDoubleList(src);
11362 switch (operation) 10910 switch (operation)
11363 { 10911 {
11364 case ScriptBaseClass.LIST_STAT_RANGE: 10912 case ScriptBaseClass.LIST_STAT_RANGE:
11365 return nums.Range(); 10913 return src.Range();
11366 case ScriptBaseClass.LIST_STAT_MIN: 10914 case ScriptBaseClass.LIST_STAT_MIN:
11367 return nums.Min(); 10915 return src.Min();
11368 case ScriptBaseClass.LIST_STAT_MAX: 10916 case ScriptBaseClass.LIST_STAT_MAX:
11369 return nums.Max(); 10917 return src.Max();
11370 case ScriptBaseClass.LIST_STAT_MEAN: 10918 case ScriptBaseClass.LIST_STAT_MEAN:
11371 return nums.Mean(); 10919 return src.Mean();
11372 case ScriptBaseClass.LIST_STAT_MEDIAN: 10920 case ScriptBaseClass.LIST_STAT_MEDIAN:
11373 return nums.Median(); 10921 return LSL_List.ToDoubleList(src).Median();
11374 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10922 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
11375 return nums.NumericLength(); 10923 return src.NumericLength();
11376 case ScriptBaseClass.LIST_STAT_STD_DEV: 10924 case ScriptBaseClass.LIST_STAT_STD_DEV:
11377 return nums.StdDev(); 10925 return src.StdDev();
11378 case ScriptBaseClass.LIST_STAT_SUM: 10926 case ScriptBaseClass.LIST_STAT_SUM:
11379 return nums.Sum(); 10927 return src.Sum();
11380 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10928 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
11381 return nums.SumSqrs(); 10929 return src.SumSqrs();
11382 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10930 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
11383 return nums.GeometricMean(); 10931 return src.GeometricMean();
11384 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10932 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
11385 return nums.HarmonicMean(); 10933 return src.HarmonicMean();
11386 default: 10934 default:
11387 return 0.0; 10935 return 0.0;
11388 } 10936 }
@@ -11740,7 +11288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11740 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 11288 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
11741 { 11289 {
11742 m_host.AddScriptLPS(1); 11290 m_host.AddScriptLPS(1);
11743 LandData land = World.GetLandData((float)pos.x, (float)pos.y); 11291 LandData land = World.GetLandData(pos);
11744 if (land == null) 11292 if (land == null)
11745 { 11293 {
11746 return new LSL_List(0); 11294 return new LSL_List(0);
@@ -11908,13 +11456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11908 else 11456 else
11909 rot = obj.GetWorldRotation(); 11457 rot = obj.GetWorldRotation();
11910 11458
11911 LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); 11459 LSL_Rotation objrot = new LSL_Rotation(rot);
11912 ret.Add(objrot); 11460 ret.Add(objrot);
11913 } 11461 }
11914 break; 11462 break;
11915 case ScriptBaseClass.OBJECT_VELOCITY: 11463 case ScriptBaseClass.OBJECT_VELOCITY:
11916 Vector3 ovel = obj.Velocity; 11464 ret.Add(new LSL_Vector(obj.Velocity));
11917 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
11918 break; 11465 break;
11919 case ScriptBaseClass.OBJECT_OWNER: 11466 case ScriptBaseClass.OBJECT_OWNER:
11920 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11467 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -12127,7 +11674,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12127 return tid.ToString(); 11674 return tid.ToString();
12128 } 11675 }
12129 11676
12130 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11677 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
12131 { 11678 {
12132 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11679 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12133 if (obj == null) 11680 if (obj == null)
@@ -12136,28 +11683,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12136 if (obj.OwnerID != m_host.OwnerID) 11683 if (obj.OwnerID != m_host.OwnerID)
12137 return; 11684 return;
12138 11685
12139 LSL_List remaining = SetPrimParams(obj, rules); 11686 uint rulesParsed = 0;
11687 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
12140 11688
12141 while ((object)remaining != null && remaining.Length > 2) 11689 while ((object)remaining != null && remaining.Length > 2)
12142 { 11690 {
12143 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11691 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
12144 LSL_List newrules = remaining.GetSublist(1, -1); 11692 LSL_List newrules = remaining.GetSublist(1, -1);
12145 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11693 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
12146 remaining = SetPrimParams(part, newrules); 11694 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
12147 } 11695 }
12148 } 11696 }
12149 } 11697 }
12150 11698
12151 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11699 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
12152 { 11700 {
12153 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11701 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12154 if (obj == null)
12155 return new LSL_List();
12156 11702
12157 if (obj.OwnerID != m_host.OwnerID) 11703 LSL_List result = new LSL_List();
12158 return new LSL_List(); 11704
11705 if (obj != null && obj.OwnerID != m_host.OwnerID)
11706 {
11707 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11708
11709 while (remaining != null && remaining.Length > 2)
11710 {
11711 int linknumber = remaining.GetLSLIntegerItem(0);
11712 rules = remaining.GetSublist(1, -1);
11713 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11714
11715 foreach (SceneObjectPart part in parts)
11716 remaining = GetPrimParams(part, rules, ref result);
11717 }
11718 }
12159 11719
12160 return GetLinkPrimitiveParams(obj, rules); 11720 return result;
12161 } 11721 }
12162 11722
12163 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 11723 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
@@ -12520,8 +12080,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12520 12080
12521 m_host.AddScriptLPS(1); 12081 m_host.AddScriptLPS(1);
12522 12082
12523 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); 12083 Vector3 rayStart = start;
12524 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); 12084 Vector3 rayEnd = end;
12525 Vector3 dir = rayEnd - rayStart; 12085 Vector3 dir = rayEnd - rayStart;
12526 12086
12527 float dist = Vector3.Mag(dir); 12087 float dist = Vector3.Mag(dir);
@@ -13095,6 +12655,455 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13095 } 12655 }
13096 } 12656 }
13097 } 12657 }
12658
12659 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12660 {
12661 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12662
12663 int idx = 0;
12664 int idxStart = 0;
12665
12666 bool positionChanged = false;
12667 Vector3 finalPos = Vector3.Zero;
12668
12669 try
12670 {
12671 while (idx < rules.Length)
12672 {
12673 ++rulesParsed;
12674 int code = rules.GetLSLIntegerItem(idx++);
12675
12676 int remain = rules.Length - idx;
12677 idxStart = idx;
12678
12679 switch (code)
12680 {
12681 case (int)ScriptBaseClass.PRIM_POSITION:
12682 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12683 {
12684 if (remain < 1)
12685 return null;
12686
12687 LSL_Vector v;
12688 v = rules.GetVector3Item(idx++);
12689
12690 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12691 if (part == null)
12692 break;
12693
12694 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12695 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12696 if (part.LinkNum > 1)
12697 {
12698 localRot = GetPartLocalRot(part);
12699 localPos = GetPartLocalPos(part);
12700 }
12701
12702 v -= localPos;
12703 v /= localRot;
12704
12705 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12706
12707 v = v + 2 * sitOffset;
12708
12709 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12710 av.SendAvatarDataToAllAgents();
12711
12712 }
12713 break;
12714
12715 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12716 case (int)ScriptBaseClass.PRIM_ROTATION:
12717 {
12718 if (remain < 1)
12719 return null;
12720
12721 LSL_Rotation r;
12722 r = rules.GetQuaternionItem(idx++);
12723
12724 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12725 if (part == null)
12726 break;
12727
12728 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12729 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12730
12731 if (part.LinkNum > 1)
12732 localRot = GetPartLocalRot(part);
12733
12734 r = r * llGetRootRotation() / localRot;
12735 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12736 av.SendAvatarDataToAllAgents();
12737 }
12738 break;
12739
12740 // parse rest doing nothing but number of parameters error check
12741 case (int)ScriptBaseClass.PRIM_SIZE:
12742 case (int)ScriptBaseClass.PRIM_MATERIAL:
12743 case (int)ScriptBaseClass.PRIM_PHANTOM:
12744 case (int)ScriptBaseClass.PRIM_PHYSICS:
12745 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12746 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12747 case (int)ScriptBaseClass.PRIM_NAME:
12748 case (int)ScriptBaseClass.PRIM_DESC:
12749 if (remain < 1)
12750 return null;
12751 idx++;
12752 break;
12753
12754 case (int)ScriptBaseClass.PRIM_GLOW:
12755 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12756 case (int)ScriptBaseClass.PRIM_TEXGEN:
12757 if (remain < 2)
12758 return null;
12759 idx += 2;
12760 break;
12761
12762 case (int)ScriptBaseClass.PRIM_TYPE:
12763 if (remain < 3)
12764 return null;
12765 code = (int)rules.GetLSLIntegerItem(idx++);
12766 remain = rules.Length - idx;
12767 switch (code)
12768 {
12769 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12770 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12771 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12772 if (remain < 6)
12773 return null;
12774 idx += 6;
12775 break;
12776
12777 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12778 if (remain < 5)
12779 return null;
12780 idx += 5;
12781 break;
12782
12783 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12784 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12785 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12786 if (remain < 11)
12787 return null;
12788 idx += 11;
12789 break;
12790
12791 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12792 if (remain < 2)
12793 return null;
12794 idx += 2;
12795 break;
12796 }
12797 break;
12798
12799 case (int)ScriptBaseClass.PRIM_COLOR:
12800 case (int)ScriptBaseClass.PRIM_TEXT:
12801 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12802 case (int)ScriptBaseClass.PRIM_OMEGA:
12803 if (remain < 3)
12804 return null;
12805 idx += 3;
12806 break;
12807
12808 case (int)ScriptBaseClass.PRIM_TEXTURE:
12809 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12810 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12811 if (remain < 5)
12812 return null;
12813 idx += 5;
12814 break;
12815
12816 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12817 if (remain < 7)
12818 return null;
12819
12820 idx += 7;
12821 break;
12822
12823 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12824 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12825 return null;
12826
12827 return rules.GetSublist(idx, -1);
12828 }
12829 }
12830 }
12831 catch (InvalidCastException e)
12832 {
12833 ShoutError(string.Format(
12834 "{0} error running rule #{1}: arg #{2} ",
12835 originFunc, rulesParsed, idx - idxStart) + e.Message);
12836 }
12837 finally
12838 {
12839 if (positionChanged)
12840 {
12841 av.OffsetPosition = finalPos;
12842// av.SendAvatarDataToAllAgents();
12843 av.SendTerseUpdateToAllClients();
12844 positionChanged = false;
12845 }
12846 }
12847 return null;
12848 }
12849
12850 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12851 {
12852 // avatars case
12853 // replies as SL wiki
12854
12855// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12856 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12857
12858 int idx = 0;
12859 while (idx < rules.Length)
12860 {
12861 int code = (int)rules.GetLSLIntegerItem(idx++);
12862 int remain = rules.Length - idx;
12863
12864 switch (code)
12865 {
12866 case (int)ScriptBaseClass.PRIM_MATERIAL:
12867 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12868 break;
12869
12870 case (int)ScriptBaseClass.PRIM_PHYSICS:
12871 res.Add(new LSL_Integer(0));
12872 break;
12873
12874 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12875 res.Add(new LSL_Integer(0));
12876 break;
12877
12878 case (int)ScriptBaseClass.PRIM_PHANTOM:
12879 res.Add(new LSL_Integer(0));
12880 break;
12881
12882 case (int)ScriptBaseClass.PRIM_POSITION:
12883
12884 Vector3 pos = avatar.OffsetPosition;
12885
12886 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12887 pos -= sitOffset;
12888
12889 if( sitPart != null)
12890 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12891
12892 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_SIZE:
12896 // as in llGetAgentSize above
12897 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12898 break;
12899
12900 case (int)ScriptBaseClass.PRIM_ROTATION:
12901 Quaternion rot = avatar.Rotation;
12902 if (sitPart != null)
12903 {
12904 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12905 }
12906
12907 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12908 break;
12909
12910 case (int)ScriptBaseClass.PRIM_TYPE:
12911 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12912 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12913 res.Add(new LSL_Vector(0f,1.0f,0f));
12914 res.Add(new LSL_Float(0.0f));
12915 res.Add(new LSL_Vector(0, 0, 0));
12916 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12917 res.Add(new LSL_Vector(0, 0, 0));
12918 break;
12919
12920 case (int)ScriptBaseClass.PRIM_TEXTURE:
12921 if (remain < 1)
12922 return null;
12923
12924 int face = (int)rules.GetLSLIntegerItem(idx++);
12925 if (face == ScriptBaseClass.ALL_SIDES)
12926 {
12927 for (face = 0; face < 21; face++)
12928 {
12929 res.Add(new LSL_String(""));
12930 res.Add(new LSL_Vector(0,0,0));
12931 res.Add(new LSL_Vector(0,0,0));
12932 res.Add(new LSL_Float(0.0));
12933 }
12934 }
12935 else
12936 {
12937 if (face >= 0 && face < 21)
12938 {
12939 res.Add(new LSL_String(""));
12940 res.Add(new LSL_Vector(0,0,0));
12941 res.Add(new LSL_Vector(0,0,0));
12942 res.Add(new LSL_Float(0.0));
12943 }
12944 }
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_COLOR:
12948 if (remain < 1)
12949 return null;
12950
12951 face = (int)rules.GetLSLIntegerItem(idx++);
12952
12953 if (face == ScriptBaseClass.ALL_SIDES)
12954 {
12955 for (face = 0; face < 21; face++)
12956 {
12957 res.Add(new LSL_Vector(0,0,0));
12958 res.Add(new LSL_Float(0));
12959 }
12960 }
12961 else
12962 {
12963 res.Add(new LSL_Vector(0,0,0));
12964 res.Add(new LSL_Float(0));
12965 }
12966 break;
12967
12968 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12969 if (remain < 1)
12970 return null;
12971 face = (int)rules.GetLSLIntegerItem(idx++);
12972
12973 if (face == ScriptBaseClass.ALL_SIDES)
12974 {
12975 for (face = 0; face < 21; face++)
12976 {
12977 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12979 }
12980 }
12981 else
12982 {
12983 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12985 }
12986 break;
12987
12988 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12989 if (remain < 1)
12990 return null;
12991 face = (int)rules.GetLSLIntegerItem(idx++);
12992
12993 if (face == ScriptBaseClass.ALL_SIDES)
12994 {
12995 for (face = 0; face < 21; face++)
12996 {
12997 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12998 }
12999 }
13000 else
13001 {
13002 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13003 }
13004 break;
13005
13006 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13007 res.Add(new LSL_Integer(0));
13008 res.Add(new LSL_Integer(0));// softness
13009 res.Add(new LSL_Float(0.0f)); // gravity
13010 res.Add(new LSL_Float(0.0f)); // friction
13011 res.Add(new LSL_Float(0.0f)); // wind
13012 res.Add(new LSL_Float(0.0f)); // tension
13013 res.Add(new LSL_Vector(0f,0f,0f));
13014 break;
13015
13016 case (int)ScriptBaseClass.PRIM_TEXGEN:
13017 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13018 if (remain < 1)
13019 return null;
13020 face = (int)rules.GetLSLIntegerItem(idx++);
13021
13022 if (face == ScriptBaseClass.ALL_SIDES)
13023 {
13024 for (face = 0; face < 21; face++)
13025 {
13026 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13027 }
13028 }
13029 else
13030 {
13031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13032 }
13033 break;
13034
13035 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13036 res.Add(new LSL_Integer(0));
13037 res.Add(new LSL_Vector(0f,0f,0f));
13038 res.Add(new LSL_Float(0f)); // intensity
13039 res.Add(new LSL_Float(0f)); // radius
13040 res.Add(new LSL_Float(0f)); // falloff
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_GLOW:
13044 if (remain < 1)
13045 return null;
13046 face = (int)rules.GetLSLIntegerItem(idx++);
13047
13048 if (face == ScriptBaseClass.ALL_SIDES)
13049 {
13050 for (face = 0; face < 21; face++)
13051 {
13052 res.Add(new LSL_Float(0f));
13053 }
13054 }
13055 else
13056 {
13057 res.Add(new LSL_Float(0f));
13058 }
13059 break;
13060
13061 case (int)ScriptBaseClass.PRIM_TEXT:
13062 res.Add(new LSL_String(""));
13063 res.Add(new LSL_Vector(0f,0f,0f));
13064 res.Add(new LSL_Float(1.0f));
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_NAME:
13068 res.Add(new LSL_String(avatar.Name));
13069 break;
13070
13071 case (int)ScriptBaseClass.PRIM_DESC:
13072 res.Add(new LSL_String(""));
13073 break;
13074
13075 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13076 Quaternion lrot = avatar.Rotation;
13077
13078 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13079 {
13080 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13081 }
13082 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13083 break;
13084
13085 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13086 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13087 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13088 lpos -= lsitOffset;
13089
13090 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13091 {
13092 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13093 }
13094 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13095 break;
13096
13097 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13098 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13099 return null;
13100
13101 return rules.GetSublist(idx, -1);
13102 }
13103 }
13104
13105 return null;
13106 }
13098 } 13107 }
13099 13108
13100 public class NotecardCache 13109 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 795de80..ceb4660 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
305 idx++; 305 idx++;
306 iV = rules.GetVector3Item(idx); 306 iV = rules.GetVector3Item(idx);
307 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 307 wl.cloudDetailXYDensity = iV;
308 break; 308 break;
309 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 309 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
310 idx++; 310 idx++;
@@ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
330 idx++; 330 idx++;
331 iV = rules.GetVector3Item(idx); 331 iV = rules.GetVector3Item(idx);
332 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 332 wl.cloudXYDensity = iV;
333 break; 333 break;
334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
335 idx++; 335 idx++;
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
385 idx++; 385 idx++;
386 iV = rules.GetVector3Item(idx); 386 iV = rules.GetVector3Item(idx);
387 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 387 wl.reflectionWaveletScale = iV;
388 break; 388 break;
389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
390 idx++; 390 idx++;
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
422 case (int)ScriptBaseClass.WL_WATER_COLOR: 422 case (int)ScriptBaseClass.WL_WATER_COLOR:
423 idx++; 423 idx++;
424 iV = rules.GetVector3Item(idx); 424 iV = rules.GetVector3Item(idx);
425 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 425 wl.waterColor = iV;
426 break; 426 break;
427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
428 idx++; 428 idx++;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 7844c75..6809c09 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -254,7 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
254 254
255 object[] convertedParms = new object[parms.Length]; 255 object[] convertedParms = new object[parms.Length];
256 for (int i = 0; i < parms.Length; i++) 256 for (int i = 0; i < parms.Length; i++)
257 convertedParms[i] = ConvertFromLSL(parms[i],signature[i]); 257 convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname);
258 258
259 // now call the function, the contract with the function is that it will always return 259 // now call the function, the contract with the function is that it will always return
260 // non-null but don't trust it completely 260 // non-null but don't trust it completely
@@ -294,7 +294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
294 294
295 /// <summary> 295 /// <summary>
296 /// </summary> 296 /// </summary>
297 protected object ConvertFromLSL(object lslparm, Type type) 297 protected object ConvertFromLSL(object lslparm, Type type, string fname)
298 { 298 {
299 // ---------- String ---------- 299 // ---------- String ----------
300 if (lslparm is LSL_String) 300 if (lslparm is LSL_String)
@@ -310,7 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
310 // ---------- Integer ---------- 310 // ---------- Integer ----------
311 else if (lslparm is LSL_Integer) 311 else if (lslparm is LSL_Integer)
312 { 312 {
313 if (type == typeof(int)) 313 if (type == typeof(int) || type == typeof(float))
314 return (int)(LSL_Integer)lslparm; 314 return (int)(LSL_Integer)lslparm;
315 } 315 }
316 316
@@ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
333 { 333 {
334 if (type == typeof(OpenMetaverse.Quaternion)) 334 if (type == typeof(OpenMetaverse.Quaternion))
335 { 335 {
336 LSL_Rotation rot = (LSL_Rotation)lslparm; 336 return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm);
337 return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
338 } 337 }
339 } 338 }
340 339
@@ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
343 { 342 {
344 if (type == typeof(OpenMetaverse.Vector3)) 343 if (type == typeof(OpenMetaverse.Vector3))
345 { 344 {
346 LSL_Vector vect = (LSL_Vector)lslparm; 345 return (OpenMetaverse.Vector3)((LSL_Vector)lslparm);
347 return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
348 } 346 }
349 } 347 }
350 348
@@ -367,23 +365,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
367 result[i] = new UUID((LSL_Key)plist[i]); 365 result[i] = new UUID((LSL_Key)plist[i]);
368 else if (plist[i] is LSL_Rotation) 366 else if (plist[i] is LSL_Rotation)
369 { 367 {
370 LSL_Rotation rot = (LSL_Rotation)plist[i]; 368 result[i] = (OpenMetaverse.Quaternion)(
371 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); 369 (LSL_Rotation)plist[i]);
372 } 370 }
373 else if (plist[i] is LSL_Vector) 371 else if (plist[i] is LSL_Vector)
374 { 372 {
375 LSL_Vector vect = (LSL_Vector)plist[i]; 373 result[i] = (OpenMetaverse.Vector3)(
376 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); 374 (LSL_Vector)plist[i]);
377 } 375 }
378 else 376 else
379 MODError("unknown LSL list element type"); 377 MODError(String.Format("{0}: unknown LSL list element type", fname));
380 } 378 }
381 379
382 return result; 380 return result;
383 } 381 }
384 } 382 }
385 383
386 MODError(String.Format("parameter type mismatch; expecting {0}",type.Name)); 384 MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname));
387 return null; 385 return null;
388 } 386 }
389 387
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 80111f9..2c682d4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -141,6 +141,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
141 internal bool m_debuggerSafe = false; 141 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 143
144 protected IUrlModule m_UrlModule = null;
145
144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 146 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
145 { 147 {
146 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
@@ -148,6 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_item = item; 150 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154
151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 155 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
152 m_OSFunctionsEnabled = true; 156 m_OSFunctionsEnabled = true;
153 157
@@ -782,10 +786,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
782 786
783 // We will launch the teleport on a new thread so that when the script threads are terminated 787 // We will launch the teleport on a new thread so that when the script threads are terminated
784 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 788 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
785 Util.FireAndForget( 789 Util.FireAndForget(o => World.RequestTeleportLocation(
786 o => World.RequestTeleportLocation(presence.ControllingClient, regionName, 790 presence.ControllingClient, regionName, position,
787 new Vector3((float)position.x, (float)position.y, (float)position.z), 791 lookat, (uint)TPFlags.ViaLocation));
788 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
789 792
790 ScriptSleep(5000); 793 ScriptSleep(5000);
791 794
@@ -828,10 +831,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 831
829 // We will launch the teleport on a new thread so that when the script threads are terminated 832 // We will launch the teleport on a new thread so that when the script threads are terminated
830 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 833 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
831 Util.FireAndForget( 834 Util.FireAndForget(o => World.RequestTeleportLocation(
832 o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, 835 presence.ControllingClient, regionHandle,
833 new Vector3((float)position.x, (float)position.y, (float)position.z), 836 position, lookat, (uint)TPFlags.ViaLocation));
834 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
835 837
836 ScriptSleep(5000); 838 ScriptSleep(5000);
837 839
@@ -1680,6 +1682,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1680 return; 1682 return;
1681 } 1683 }
1682 1684
1685 MessageObject(objUUID, message);
1686 }
1687
1688 private void MessageObject(UUID objUUID, string message)
1689 {
1683 object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) }; 1690 object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) };
1684 1691
1685 SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID); 1692 SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID);
@@ -2259,11 +2266,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2266 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
2260 m_host.AddScriptLPS(1); 2267 m_host.AddScriptLPS(1);
2261 InitLSL(); 2268 InitLSL();
2269 // One needs to cast m_LSL_Api because we're using functions not
2270 // on the ILSL_Api interface.
2271 LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
2262 LSL_List retVal = new LSL_List(); 2272 LSL_List retVal = new LSL_List();
2263 List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber); 2273 LSL_List remaining = null;
2274 List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
2264 foreach (SceneObjectPart part in parts) 2275 foreach (SceneObjectPart part in parts)
2265 { 2276 {
2266 retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules); 2277 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2278 }
2279
2280 while (remaining != null && remaining.Length > 2)
2281 {
2282 linknumber = remaining.GetLSLIntegerItem(0);
2283 rules = remaining.GetSublist(1, -1);
2284 parts = LSL_Api.GetLinkParts(linknumber);
2285
2286 foreach (SceneObjectPart part in parts)
2287 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2267 } 2288 }
2268 return retVal; 2289 return retVal;
2269 } 2290 }
@@ -2362,7 +2383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2362 ownerID = m_host.OwnerID; 2383 ownerID = m_host.OwnerID;
2363 UUID x = module.CreateNPC(firstname, 2384 UUID x = module.CreateNPC(firstname,
2364 lastname, 2385 lastname,
2365 new Vector3((float) position.x, (float) position.y, (float) position.z), 2386 position,
2366 ownerID, 2387 ownerID,
2367 senseAsAgent, 2388 senseAsAgent,
2368 World, 2389 World,
@@ -2485,7 +2506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2485 return new LSL_Vector(0, 0, 0); 2506 return new LSL_Vector(0, 0, 0);
2486 } 2507 }
2487 2508
2488 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2509 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2489 { 2510 {
2490 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2511 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2491 m_host.AddScriptLPS(1); 2512 m_host.AddScriptLPS(1);
@@ -2500,7 +2521,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2521 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2501 return; 2522 return;
2502 2523
2503 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2504 module.MoveToTarget(npcId, World, pos, false, true, false); 2524 module.MoveToTarget(npcId, World, pos, false, true, false);
2505 } 2525 }
2506 } 2526 }
@@ -2520,11 +2540,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2520 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2540 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2521 return; 2541 return;
2522 2542
2523 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2524 module.MoveToTarget( 2543 module.MoveToTarget(
2525 new UUID(npc.m_string), 2544 new UUID(npc.m_string),
2526 World, 2545 World,
2527 pos, 2546 target,
2528 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, 2547 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2529 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, 2548 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
2530 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); 2549 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
@@ -2576,7 +2595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2576 ScenePresence sp = World.GetScenePresence(npcId); 2595 ScenePresence sp = World.GetScenePresence(npcId);
2577 2596
2578 if (sp != null) 2597 if (sp != null)
2579 sp.Rotation = LSL_Api.Rot2Quaternion(rotation); 2598 sp.Rotation = rotation;
2580 } 2599 }
2581 } 2600 }
2582 2601
@@ -2936,7 +2955,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2936 avatar.SpeedModifier = (float)SpeedModifier; 2955 avatar.SpeedModifier = (float)SpeedModifier;
2937 } 2956 }
2938 2957
2939 public void osKickAvatar(string FirstName,string SurName,string alert) 2958 public void osKickAvatar(string FirstName, string SurName, string alert)
2940 { 2959 {
2941 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2960 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2942 m_host.AddScriptLPS(1); 2961 m_host.AddScriptLPS(1);
@@ -2950,10 +2969,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2950 sp.ControllingClient.Kick(alert); 2969 sp.ControllingClient.Kick(alert);
2951 2970
2952 // ...and close on our side 2971 // ...and close on our side
2953 sp.Scene.IncomingCloseAgent(sp.UUID); 2972 sp.Scene.IncomingCloseAgent(sp.UUID, false);
2954 } 2973 }
2955 }); 2974 });
2956 } 2975 }
2976
2977 public LSL_Float osGetHealth(string avatar)
2978 {
2979 CheckThreatLevel(ThreatLevel.None, "osGetHealth");
2980 m_host.AddScriptLPS(1);
2981
2982 LSL_Float health = new LSL_Float(-1);
2983 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
2984 if (presence != null) health = presence.Health;
2985 return health;
2986 }
2957 2987
2958 public void osCauseDamage(string avatar, double damage) 2988 public void osCauseDamage(string avatar, double damage)
2959 { 2989 {
@@ -2966,7 +2996,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2966 ScenePresence presence = World.GetScenePresence(avatarId); 2996 ScenePresence presence = World.GetScenePresence(avatarId);
2967 if (presence != null) 2997 if (presence != null)
2968 { 2998 {
2969 LandData land = World.GetLandData((float)pos.X, (float)pos.Y); 2999 LandData land = World.GetLandData(pos);
2970 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage) 3000 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage)
2971 { 3001 {
2972 float health = presence.Health; 3002 float health = presence.Health;
@@ -3013,7 +3043,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 m_host.AddScriptLPS(1); 3043 m_host.AddScriptLPS(1);
3014 InitLSL(); 3044 InitLSL();
3015 3045
3016 return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules); 3046 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3017 } 3047 }
3018 3048
3019 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3049 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
@@ -3022,7 +3052,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 m_host.AddScriptLPS(1); 3052 m_host.AddScriptLPS(1);
3023 InitLSL(); 3053 InitLSL();
3024 3054
3025 m_LSL_Api.SetPrimitiveParamsEx(prim, rules); 3055 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3026 } 3056 }
3027 3057
3028 /// <summary> 3058 /// <summary>
@@ -3254,6 +3284,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3254 } 3284 }
3255 } 3285 }
3256 3286
3287 #region Attachment commands
3288
3257 public void osForceAttachToAvatar(int attachmentPoint) 3289 public void osForceAttachToAvatar(int attachmentPoint)
3258 { 3290 {
3259 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); 3291 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
@@ -3343,6 +3375,175 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3343 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3375 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3344 } 3376 }
3345 3377
3378 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
3379 {
3380 CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
3381
3382 m_host.AddScriptLPS(1);
3383
3384 UUID targetUUID;
3385 ScenePresence target;
3386 LSL_List resp = new LSL_List();
3387
3388 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3389 {
3390 foreach (object point in attachmentPoints.Data)
3391 {
3392 LSL_Integer ipoint = new LSL_Integer(
3393 (point is LSL_Integer || point is int || point is uint) ?
3394 (int)point :
3395 0
3396 );
3397 resp.Add(ipoint);
3398 if (ipoint == 0)
3399 {
3400 // indicates zero attachments
3401 resp.Add(new LSL_Integer(0));
3402 }
3403 else
3404 {
3405 // gets the number of attachments on the attachment point
3406 resp.Add(new LSL_Integer(target.GetAttachments((uint)ipoint).Count));
3407 }
3408 }
3409 }
3410
3411 return resp;
3412 }
3413
3414 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
3415 {
3416 CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
3417 m_host.AddScriptLPS(1);
3418
3419 UUID targetUUID;
3420 ScenePresence target;
3421
3422 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3423 {
3424 List<int> aps = new List<int>();
3425 foreach (object point in attachmentPoints.Data)
3426 {
3427 int ipoint;
3428 if (int.TryParse(point.ToString(), out ipoint))
3429 {
3430 aps.Add(ipoint);
3431 }
3432 }
3433
3434 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3435
3436 bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3437 bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
3438
3439 if (msgAll && invertPoints)
3440 {
3441 return;
3442 }
3443 else if (msgAll || invertPoints)
3444 {
3445 attachments = target.GetAttachments();
3446 }
3447 else
3448 {
3449 foreach (int point in aps)
3450 {
3451 if (point > 0)
3452 {
3453 attachments.AddRange(target.GetAttachments((uint)point));
3454 }
3455 }
3456 }
3457
3458 // if we have no attachments at this point, exit now
3459 if (attachments.Count == 0)
3460 {
3461 return;
3462 }
3463
3464 List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>();
3465
3466 if (invertPoints)
3467 {
3468 foreach (SceneObjectGroup attachment in attachments)
3469 {
3470 if (aps.Contains((int)attachment.AttachmentPoint))
3471 {
3472 ignoreThese.Add(attachment);
3473 }
3474 }
3475 }
3476
3477 foreach (SceneObjectGroup attachment in ignoreThese)
3478 {
3479 attachments.Remove(attachment);
3480 }
3481 ignoreThese.Clear();
3482
3483 // if inverting removed all attachments to check, exit now
3484 if (attachments.Count < 1)
3485 {
3486 return;
3487 }
3488
3489 if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0)
3490 {
3491 foreach (SceneObjectGroup attachment in attachments)
3492 {
3493 if (attachment.RootPart.CreatorID != m_host.CreatorID)
3494 {
3495 ignoreThese.Add(attachment);
3496 }
3497 }
3498
3499 foreach (SceneObjectGroup attachment in ignoreThese)
3500 {
3501 attachments.Remove(attachment);
3502 }
3503 ignoreThese.Clear();
3504
3505 // if filtering by same object creator removed all
3506 // attachments to check, exit now
3507 if (attachments.Count == 0)
3508 {
3509 return;
3510 }
3511 }
3512
3513 if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0)
3514 {
3515 foreach (SceneObjectGroup attachment in attachments)
3516 {
3517 if (attachment.RootPart.CreatorID != m_item.CreatorID)
3518 {
3519 ignoreThese.Add(attachment);
3520 }
3521 }
3522
3523 foreach (SceneObjectGroup attachment in ignoreThese)
3524 {
3525 attachments.Remove(attachment);
3526 }
3527 ignoreThese.Clear();
3528
3529 // if filtering by object creator must match originating
3530 // script creator removed all attachments to check,
3531 // exit now
3532 if (attachments.Count == 0)
3533 {
3534 return;
3535 }
3536 }
3537
3538 foreach (SceneObjectGroup attachment in attachments)
3539 {
3540 MessageObject(attachment.RootPart.UUID, message);
3541 }
3542 }
3543 }
3544
3545 #endregion
3546
3346 /// <summary> 3547 /// <summary>
3347 /// Checks if thing is a UUID. 3548 /// Checks if thing is a UUID.
3348 /// </summary> 3549 /// </summary>
@@ -3392,5 +3593,103 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3392 3593
3393 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3594 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3394 } 3595 }
3596
3597 /// <summary>
3598 /// Sets the response type for an HTTP request/response
3599 /// </summary>
3600 /// <returns></returns>
3601 public void osSetContentType(LSL_Key id, string type)
3602 {
3603 CheckThreatLevel(ThreatLevel.High,"osSetResponseType");
3604 if (m_UrlModule != null)
3605 m_UrlModule.HttpContentType(new UUID(id),type);
3606 }
3607
3608 /// Shout an error if the object owner did not grant the script the specified permissions.
3609 /// </summary>
3610 /// <param name="perms"></param>
3611 /// <returns>boolean indicating whether an error was shouted.</returns>
3612 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix)
3613 {
3614 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment");
3615 m_host.AddScriptLPS(1);
3616 bool fail = false;
3617 if (m_item.PermsGranter != m_host.OwnerID)
3618 {
3619 fail = true;
3620 OSSLShoutError(string.Format("{0}. Permissions not granted to owner.", errorPrefix));
3621 }
3622 else if ((m_item.PermsMask & perms) == 0)
3623 {
3624 fail = true;
3625 OSSLShoutError(string.Format("{0}. Permissions not granted.", errorPrefix));
3626 }
3627
3628 return fail;
3629 }
3630
3631 protected void DropAttachment(bool checkPerms)
3632 {
3633 if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
3634 {
3635 return;
3636 }
3637
3638 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3639 ScenePresence sp = attachmentsModule == null ? null : m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.OwnerID);
3640
3641 if (attachmentsModule != null && sp != null)
3642 {
3643 attachmentsModule.DetachSingleAttachmentToGround(sp, m_host.ParentGroup.LocalId);
3644 }
3645 }
3646
3647 protected void DropAttachmentAt(bool checkPerms, LSL_Vector pos, LSL_Rotation rot)
3648 {
3649 if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
3650 {
3651 return;
3652 }
3653
3654 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3655 ScenePresence sp = attachmentsModule == null ? null : m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.OwnerID);
3656
3657 if (attachmentsModule != null && sp != null)
3658 {
3659 attachmentsModule.DetachSingleAttachmentToGround(sp, m_host.ParentGroup.LocalId, pos, rot);
3660 }
3661 }
3662
3663 public void osDropAttachment()
3664 {
3665 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment");
3666 m_host.AddScriptLPS(1);
3667
3668 DropAttachment(true);
3669 }
3670
3671 public void osForceDropAttachment()
3672 {
3673 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment");
3674 m_host.AddScriptLPS(1);
3675
3676 DropAttachment(false);
3677 }
3678
3679 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3680 {
3681 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt");
3682 m_host.AddScriptLPS(1);
3683
3684 DropAttachmentAt(true, pos, rot);
3685 }
3686
3687 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3688 {
3689 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt");
3690 m_host.AddScriptLPS(1);
3691
3692 DropAttachmentAt(false, pos, rot);
3693 }
3395 } 3694 }
3396} 3695}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 678f9d5..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
352 q = avatar.Rotation; 352 q = avatar.Rotation;
353 } 353 }
354 354
355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
358 358
@@ -429,9 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 try 429 try
430 { 430 {
431 Vector3 diff = toRegionPos - fromRegionPos; 431 Vector3 diff = toRegionPos - fromRegionPos;
432 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 432 double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
433 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 433 double mag_obj = LSL_Types.Vector3.Mag(diff);
434 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
435 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 434 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
436 } 435 }
437 catch 436 catch
@@ -483,7 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
483 q = avatar.Rotation; 482 q = avatar.Rotation;
484 } 483 }
485 484
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
487 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 486 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
488 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 487 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
489 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); 488 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
@@ -564,8 +563,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
564 double ang_obj = 0; 563 double ang_obj = 0;
565 try 564 try
566 { 565 {
567 Vector3 diff = toRegionPos - fromRegionPos; 566 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(
568 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 567 toRegionPos - fromRegionPos);
569 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 568 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
570 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); 569 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
571 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 570 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index af35258..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -429,8 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density); 430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
431 431
432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
435 } 435 }
436} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 8c34ed3..b1fbed5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
40 40
41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 /// <summary>
44 /// To permit region owners to enable the extended scripting functionality
45 /// of OSSL, without allowing malicious scripts to access potentially
46 /// troublesome functions, each OSSL function is assigned a threat level,
47 /// and access to the functions is granted or denied based on a default
48 /// threshold set in OpenSim.ini (which can be overridden for individual
49 /// functions on a case-by-case basis)
50 /// </summary>
43 public enum ThreatLevel 51 public enum ThreatLevel
44 { 52 {
53 // Not documented, presumably means permanently disabled ?
45 NoAccess = -1, 54 NoAccess = -1,
55
56 /// <summary>
57 /// Function is no threat at all. It doesn't constitute a threat to
58 /// either users or the system and has no known side effects.
59 /// </summary>
46 None = 0, 60 None = 0,
61
62 /// <summary>
63 /// Abuse of this command can cause a nuisance to the region operator,
64 /// such as log message spew.
65 /// </summary>
47 Nuisance = 1, 66 Nuisance = 1,
67
68 /// <summary>
69 /// Extreme levels of abuse of this function can cause impaired
70 /// functioning of the region, or very gullible users can be tricked
71 /// into experiencing harmless effects.
72 /// </summary>
48 VeryLow = 2, 73 VeryLow = 2,
74
75 /// <summary>
76 /// Intentional abuse can cause crashes or malfunction under certain
77 /// circumstances, which can be easily rectified; or certain users can
78 /// be tricked into certain situations in an avoidable manner.
79 /// </summary>
49 Low = 3, 80 Low = 3,
81
82 /// <summary>
83 /// Intentional abuse can cause denial of service and crashes with
84 /// potential of data or state loss; or trusting users can be tricked
85 /// into embarrassing or uncomfortable situations.
86 /// </summary>
50 Moderate = 4, 87 Moderate = 4,
88
89 /// <summary>
90 /// Casual abuse can cause impaired functionality or temporary denial
91 /// of service conditions. Intentional abuse can easily cause crashes
92 /// with potential data loss, or can be used to trick experienced and
93 /// cautious users into unwanted situations, or changes global data
94 /// permanently and without undo ability.
95 /// </summary>
51 High = 5, 96 High = 5,
97
98 /// <summary>
99 /// Even normal use may, depending on the number of instances, or
100 /// frequency of use, result in severe service impairment or crash
101 /// with loss of data, or can be used to cause unwanted or harmful
102 /// effects on users without giving the user a means to avoid it.
103 /// </summary>
52 VeryHigh = 6, 104 VeryHigh = 6,
105
106 /// <summary>
107 /// Even casual use is a danger to region stability, or function allows
108 /// console or OS command execution, or function allows taking money
109 /// without consent, or allows deletion or modification of user data,
110 /// or allows the compromise of sensitive data by design.
111 /// </summary>
53 Severe = 7 112 Severe = 7
54 }; 113 };
55 114
@@ -98,7 +157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
98 void osAvatarPlayAnimation(string avatar, string animation); 157 void osAvatarPlayAnimation(string avatar, string animation);
99 void osAvatarStopAnimation(string avatar, string animation); 158 void osAvatarStopAnimation(string avatar, string animation);
100 159
101 // Attachment commands 160 #region Attachment commands
102 161
103 /// <summary> 162 /// <summary>
104 /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH 163 /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH
@@ -133,6 +192,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
133 /// <remarks>Nothing happens if the object is not attached.</remarks> 192 /// <remarks>Nothing happens if the object is not attached.</remarks>
134 void osForceDetachFromAvatar(); 193 void osForceDetachFromAvatar();
135 194
195 /// <summary>
196 /// Returns a strided list of the specified attachment points and the number of attachments on those points.
197 /// </summary>
198 /// <param name="avatar">avatar UUID</param>
199 /// <param name="attachmentPoints">list of ATTACH_* constants</param>
200 /// <returns></returns>
201 LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints);
202
203 /// <summary>
204 /// Sends a specified message to the specified avatar's attachments on
205 /// the specified attachment points.
206 /// </summary>
207 /// <remarks>
208 /// Behaves as osMessageObject(), without the sending script needing to know the attachment keys in advance.
209 /// </remarks>
210 /// <param name="avatar">avatar UUID</param>
211 /// <param name="message">message string</param>
212 /// <param name="attachmentPoints">list of ATTACH_* constants, or -1 for all attachments. If -1 is specified and OS_ATTACH_MSG_INVERT_POINTS is present in flags, no action is taken.</param>
213 /// <param name="flags">flags further constraining the attachments to deliver the message to.</param>
214 void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags);
215
216 #endregion
217
136 //texture draw functions 218 //texture draw functions
137 string osMovePen(string drawList, int x, int y); 219 string osMovePen(string drawList, int x, int y);
138 string osDrawLine(string drawList, int startX, int startY, int endX, int endY); 220 string osDrawLine(string drawList, int startX, int startY, int endX, int endY);
@@ -258,6 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
258 int osGetSimulatorMemory(); 340 int osGetSimulatorMemory();
259 void osKickAvatar(string FirstName,string SurName,string alert); 341 void osKickAvatar(string FirstName,string SurName,string alert);
260 void osSetSpeed(string UUID, LSL_Float SpeedModifier); 342 void osSetSpeed(string UUID, LSL_Float SpeedModifier);
343 LSL_Float osGetHealth(string avatar);
261 void osCauseHealing(string avatar, double healing); 344 void osCauseHealing(string avatar, double healing);
262 void osCauseDamage(string avatar, double damage); 345 void osCauseDamage(string avatar, double damage);
263 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); 346 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
@@ -305,5 +388,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
305 /// </summary> 388 /// </summary>
306 /// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns> 389 /// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns>
307 LSL_Key osGetRezzingObject(); 390 LSL_Key osGetRezzingObject();
391
392 /// <summary>
393 /// Sets the response type for an HTTP request/response
394 /// </summary>
395 /// <returns></returns>
396 void osSetContentType(LSL_Key id, string type);
397
398 /// <summary>
399 /// Attempts to drop an attachment to the ground
400 /// </summary>
401 void osDropAttachment();
402
403 /// <summary>
404 /// Attempts to drop an attachment to the ground while bypassing the script permissions
405 /// </summary>
406 void osForceDropAttachment();
407
408 /// <summary>
409 /// Attempts to drop an attachment at the specified coordinates.
410 /// </summary>
411 /// <param name="pos"></param>
412 /// <param name="rot"></param>
413 void osDropAttachmentAt(vector pos, rotation rot);
414
415 /// <summary>
416 /// Attempts to drop an attachment at the specified coordinates while bypassing the script permissions
417 /// </summary>
418 /// <param name="pos"></param>
419 /// <param name="rot"></param>
420 void osForceDropAttachmentAt(vector pos, rotation rot);
308 } 421 }
309} 422}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index f989cc6..c788407 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -237,6 +237,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
237 public const int ATTACH_HUD_BOTTOM = 37; 237 public const int ATTACH_HUD_BOTTOM = 37;
238 public const int ATTACH_HUD_BOTTOM_RIGHT = 38; 238 public const int ATTACH_HUD_BOTTOM_RIGHT = 38;
239 239
240 #region osMessageAttachments constants
241
242 /// <summary>
243 /// Instructs osMessageAttachements to send the message to attachments
244 /// on every point.
245 /// </summary>
246 /// <remarks>
247 /// One might expect this to be named OS_ATTACH_ALL, but then one might
248 /// also expect functions designed to attach or detach or get
249 /// attachments to work with it too. Attaching a no-copy item to
250 /// many attachments could be dangerous.
251 /// when combined with OS_ATTACH_MSG_INVERT_POINTS, will prevent the
252 /// message from being sent.
253 /// if combined with OS_ATTACH_MSG_OBJECT_CREATOR or
254 /// OS_ATTACH_MSG_SCRIPT_CREATOR, could result in no message being
255 /// sent- this is expected behaviour.
256 /// </remarks>
257 public const int OS_ATTACH_MSG_ALL = -65535;
258
259 /// <summary>
260 /// Instructs osMessageAttachements to invert how the attachment points
261 /// list should be treated (e.g. go from inclusive operation to
262 /// exclusive operation).
263 /// </summary>
264 /// <remarks>
265 /// This might be used if you want to deliver a message to one set of
266 /// attachments and a different message to everything else. With
267 /// this flag, you only need to build one explicit list for both calls.
268 /// </remarks>
269 public const int OS_ATTACH_MSG_INVERT_POINTS = 1;
270
271 /// <summary>
272 /// Instructs osMessageAttachments to only send the message to
273 /// attachments with a CreatorID that matches the host object CreatorID
274 /// </summary>
275 /// <remarks>
276 /// This would be used if distributed in an object vendor/updater server.
277 /// </remarks>
278 public const int OS_ATTACH_MSG_OBJECT_CREATOR = 2;
279
280 /// <summary>
281 /// Instructs osMessageAttachments to only send the message to
282 /// attachments with a CreatorID that matches the sending script CreatorID
283 /// </summary>
284 /// <remarks>
285 /// This might be used if the script is distributed independently of a
286 /// containing object.
287 /// </remarks>
288 public const int OS_ATTACH_MSG_SCRIPT_CREATOR = 4;
289
290 #endregion
291
240 public const int LAND_LEVEL = 0; 292 public const int LAND_LEVEL = 0;
241 public const int LAND_RAISE = 1; 293 public const int LAND_RAISE = 1;
242 public const int LAND_LOWER = 2; 294 public const int LAND_LOWER = 2;
@@ -329,6 +381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
329 public const int PRIM_OMEGA = 32; 381 public const int PRIM_OMEGA = 32;
330 public const int PRIM_POS_LOCAL = 33; 382 public const int PRIM_POS_LOCAL = 33;
331 public const int PRIM_LINK_TARGET = 34; 383 public const int PRIM_LINK_TARGET = 34;
384 public const int PRIM_SLICE = 35;
332 public const int PRIM_TEXGEN_DEFAULT = 0; 385 public const int PRIM_TEXGEN_DEFAULT = 0;
333 public const int PRIM_TEXGEN_PLANAR = 1; 386 public const int PRIM_TEXGEN_PLANAR = 1;
334 387
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 94405d2..dee1b28 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -289,7 +289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation); 289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation);
290 } 290 }
291 291
292 // Avatar functions 292 #region Attachment commands
293 293
294 public void osForceAttachToAvatar(int attachmentPoint) 294 public void osForceAttachToAvatar(int attachmentPoint)
295 { 295 {
@@ -311,6 +311,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
311 m_OSSL_Functions.osForceDetachFromAvatar(); 311 m_OSSL_Functions.osForceDetachFromAvatar();
312 } 312 }
313 313
314 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
315 {
316 return m_OSSL_Functions.osGetNumberOfAttachments(avatar, attachmentPoints);
317 }
318
319 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags)
320 {
321 m_OSSL_Functions.osMessageAttachments(avatar, message, attachmentPoints, flags);
322 }
323
324 #endregion
325
314 // Texture Draw functions 326 // Texture Draw functions
315 327
316 public string osMovePen(string drawList, int x, int y) 328 public string osMovePen(string drawList, int x, int y)
@@ -865,7 +877,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
865 { 877 {
866 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); 878 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
867 } 879 }
868 880
881 public LSL_Float osGetHealth(string avatar)
882 {
883 return m_OSSL_Functions.osGetHealth(avatar);
884 }
885
869 public void osCauseDamage(string avatar, double damage) 886 public void osCauseDamage(string avatar, double damage)
870 { 887 {
871 m_OSSL_Functions.osCauseDamage(avatar, damage); 888 m_OSSL_Functions.osCauseDamage(avatar, damage);
@@ -950,5 +967,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
950 { 967 {
951 return m_OSSL_Functions.osGetRezzingObject(); 968 return m_OSSL_Functions.osGetRezzingObject();
952 } 969 }
970
971 public void osSetContentType(LSL_Key id, string type)
972 {
973 m_OSSL_Functions.osSetContentType(id,type);
974 }
975
976 public void osDropAttachment()
977 {
978 m_OSSL_Functions.osDropAttachment();
979 }
980
981 public void osForceDropAttachment()
982 {
983 m_OSSL_Functions.osForceDropAttachment();
984 }
985
986 public void osDropAttachmentAt(vector pos, rotation rot)
987 {
988 m_OSSL_Functions.osDropAttachmentAt(pos, rot);
989 }
990
991 public void osForceDropAttachmentAt(vector pos, rotation rot)
992 {
993 m_OSSL_Functions.osForceDropAttachmentAt(pos, rot);
994 }
953 } 995 }
954} 996}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 17a0d69..03be2ab 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
546 "OpenSim.Region.ScriptEngine.Shared.dll")); 546 "OpenSim.Region.ScriptEngine.Shared.dll"));
547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); 548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll"));
549 551
550 if (lang == enumCompileType.yp) 552 if (lang == enumCompileType.yp)
551 { 553 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 9e5fb24..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -164,11 +164,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
164 else 164 else
165 { 165 {
166 // Set the values from the touch data provided by the client 166 // Set the values from the touch data provided by the client
167 touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z); 167 touchST = new LSL_Types.Vector3(value.STCoord);
168 touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z); 168 touchUV = new LSL_Types.Vector3(value.UVCoord);
169 touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z); 169 touchNormal = new LSL_Types.Vector3(value.Normal);
170 touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z); 170 touchBinormal = new LSL_Types.Vector3(value.Binormal);
171 touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z); 171 touchPos = new LSL_Types.Vector3(value.Position);
172 touchFace = value.FaceIndex; 172 touchFace = value.FaceIndex;
173 } 173 }
174 } 174 }
@@ -189,19 +189,13 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 Country = account.UserCountry; 189 Country = account.UserCountry;
190 190
191 Owner = Key; 191 Owner = Key;
192 Position = new LSL_Types.Vector3( 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
193 presence.AbsolutePosition.X,
194 presence.AbsolutePosition.Y,
195 presence.AbsolutePosition.Z);
196 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
197 presence.Rotation.X, 194 presence.Rotation.X,
198 presence.Rotation.Y, 195 presence.Rotation.Y,
199 presence.Rotation.Z, 196 presence.Rotation.Z,
200 presence.Rotation.W); 197 presence.Rotation.W);
201 Velocity = new LSL_Types.Vector3( 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
202 presence.Velocity.X,
203 presence.Velocity.Y,
204 presence.Velocity.Z);
205 199
206 Type = 0x01; // Avatar 200 Type = 0x01; // Avatar
207 if (presence.PresenceType == PresenceType.Npc) 201 if (presence.PresenceType == PresenceType.Npc)
@@ -254,16 +248,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
254 } 248 }
255 } 249 }
256 250
257 Position = new LSL_Types.Vector3(part.AbsolutePosition.X, 251 Position = new LSL_Types.Vector3(part.AbsolutePosition);
258 part.AbsolutePosition.Y,
259 part.AbsolutePosition.Z);
260 252
261 Quaternion wr = part.ParentGroup.GroupRotation; 253 Quaternion wr = part.ParentGroup.GroupRotation;
262 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); 254 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W);
263 255
264 Velocity = new LSL_Types.Vector3(part.Velocity.X, 256 Velocity = new LSL_Types.Vector3(part.Velocity);
265 part.Velocity.Y,
266 part.Velocity.Z);
267 } 257 }
268 } 258 }
269 259
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 8adf4c5..c9c4753 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -31,6 +31,11 @@ using System.Globalization;
31using System.Text.RegularExpressions; 31using System.Text.RegularExpressions;
32using OpenSim.Framework; 32using OpenSim.Framework;
33 33
34using OpenMetaverse;
35using OMV_Vector3 = OpenMetaverse.Vector3;
36using OMV_Vector3d = OpenMetaverse.Vector3d;
37using OMV_Quaternion = OpenMetaverse.Quaternion;
38
34namespace OpenSim.Region.ScriptEngine.Shared 39namespace OpenSim.Region.ScriptEngine.Shared
35{ 40{
36 [Serializable] 41 [Serializable]
@@ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared
54 z = (float)vector.z; 59 z = (float)vector.z;
55 } 60 }
56 61
62 public Vector3(OMV_Vector3 vector)
63 {
64 x = vector.X;
65 y = vector.Y;
66 z = vector.Z;
67 }
68
69 public Vector3(OMV_Vector3d vector)
70 {
71 x = vector.X;
72 y = vector.Y;
73 z = vector.Z;
74 }
75
57 public Vector3(double X, double Y, double Z) 76 public Vector3(double X, double Y, double Z)
58 { 77 {
59 x = X; 78 x = X;
@@ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared
109 return new list(new object[] { vec }); 128 return new list(new object[] { vec });
110 } 129 }
111 130
131 public static implicit operator OMV_Vector3(Vector3 vec)
132 {
133 return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
134 }
135
136 public static implicit operator Vector3(OMV_Vector3 vec)
137 {
138 return new Vector3(vec);
139 }
140
141 public static implicit operator OMV_Vector3d(Vector3 vec)
142 {
143 return new OMV_Vector3d(vec.x, vec.y, vec.z);
144 }
145
146 public static implicit operator Vector3(OMV_Vector3d vec)
147 {
148 return new Vector3(vec);
149 }
150
112 public static bool operator ==(Vector3 lhs, Vector3 rhs) 151 public static bool operator ==(Vector3 lhs, Vector3 rhs)
113 { 152 {
114 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); 153 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
@@ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared
322 s = 1; 361 s = 1;
323 } 362 }
324 363
364 public Quaternion(OMV_Quaternion rot)
365 {
366 x = rot.X;
367 y = rot.Y;
368 z = rot.Z;
369 s = rot.W;
370 }
371
325 #endregion 372 #endregion
326 373
327 #region Overriders 374 #region Overriders
@@ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared
368 return new list(new object[] { r }); 415 return new list(new object[] { r });
369 } 416 }
370 417
418 public static implicit operator OMV_Quaternion(Quaternion rot)
419 {
420 // LSL quaternions can normalize to 0, normal Quaternions can't.
421 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
422 rot.z = 1; // ZERO_ROTATION = 0,0,0,1
423 OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
424 omvrot.Normalize();
425 return omvrot;
426 }
427
428 public static implicit operator Quaternion(OMV_Quaternion rot)
429 {
430 return new Quaternion(rot);
431 }
432
371 public static bool operator ==(Quaternion lhs, Quaternion rhs) 433 public static bool operator ==(Quaternion lhs, Quaternion rhs)
372 { 434 {
373 // Return true if the fields match: 435 // Return true if the fields match:
@@ -562,12 +624,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
562 else if (m_data[itemIndex] is LSL_Types.LSLString) 624 else if (m_data[itemIndex] is LSL_Types.LSLString)
563 return new LSLInteger(m_data[itemIndex].ToString()); 625 return new LSLInteger(m_data[itemIndex].ToString());
564 else 626 else
565 throw new InvalidCastException(); 627 throw new InvalidCastException(string.Format(
628 "{0} expected but {1} given",
629 typeof(LSL_Types.LSLInteger).Name,
630 m_data[itemIndex] != null ?
631 m_data[itemIndex].GetType().Name : "null"));
566 } 632 }
567 633
568 public LSL_Types.Vector3 GetVector3Item(int itemIndex) 634 public LSL_Types.Vector3 GetVector3Item(int itemIndex)
569 { 635 {
570 return (LSL_Types.Vector3)m_data[itemIndex]; 636 if(m_data[itemIndex] is LSL_Types.Vector3)
637 return (LSL_Types.Vector3)m_data[itemIndex];
638 else
639 throw new InvalidCastException(string.Format(
640 "{0} expected but {1} given",
641 typeof(LSL_Types.Vector3).Name,
642 m_data[itemIndex] != null ?
643 m_data[itemIndex].GetType().Name : "null"));
571 } 644 }
572 645
573 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) 646 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
new file mode 100644
index 0000000..dd23be8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using NUnit.Framework;
31using OpenSim.Framework;
32using OpenSim.Tests.Common;
33using OpenSim.Region.ScriptEngine.Shared;
34using OpenSim.Region.Framework.Scenes;
35using Nini.Config;
36using OpenSim.Region.ScriptEngine.Shared.Api;
37using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
38using OpenMetaverse;
39using OpenSim.Tests.Common.Mock;
40
41using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
42using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
43using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
44using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
45
46namespace OpenSim.Region.ScriptEngine.Shared.Tests
47{
48 [TestFixture]
49 public class LSL_ApiListTests
50 {
51 private LSL_Api m_lslApi;
52
53 [SetUp]
54 public void SetUp()
55 {
56 IConfigSource initConfigSource = new IniConfigSource();
57 IConfig config = initConfigSource.AddConfig("XEngine");
58 config.Set("Enabled", "true");
59
60 Scene scene = new SceneHelpers().SetupScene();
61 SceneObjectPart part = SceneHelpers.AddSceneObject(scene).RootPart;
62
63 XEngine.XEngine engine = new XEngine.XEngine();
64 engine.Initialise(initConfigSource);
65 engine.AddRegion(scene);
66
67 m_lslApi = new LSL_Api();
68 m_lslApi.Initialize(engine, part, null);
69 }
70
71 [Test]
72 public void TestllListFindList()
73 {
74 TestHelpers.InMethod();
75
76 LSL_List src = new LSL_List(new LSL_Integer(1), new LSL_Integer(2), new LSL_Integer(3));
77
78 {
79 // Test for a single item that should be found
80 int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(4)));
81 Assert.That(result, Is.EqualTo(-1));
82 }
83
84 {
85 // Test for a single item that should be found
86 int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(2)));
87 Assert.That(result, Is.EqualTo(1));
88 }
89
90 {
91 // Test for a constant that should be found
92 int result = m_lslApi.llListFindList(src, new LSL_List(ScriptBaseClass.AGENT));
93 Assert.That(result, Is.EqualTo(0));
94 }
95
96 {
97 // Test for a list that should be found
98 int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(2), new LSL_Integer(3)));
99 Assert.That(result, Is.EqualTo(1));
100 }
101
102 {
103 // Test for a single item not in the list
104 int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_Integer(4)));
105 Assert.That(result, Is.EqualTo(-1));
106 }
107
108 {
109 // Test for something that should not be cast
110 int result = m_lslApi.llListFindList(src, new LSL_List(new LSL_String("4")));
111 Assert.That(result, Is.EqualTo(-1));
112 }
113
114 {
115 // Test for a list not in the list
116 int result
117 = m_lslApi.llListFindList(
118 src, new LSL_List(new LSL_Integer(2), new LSL_Integer(3), new LSL_Integer(4)));
119 Assert.That(result, Is.EqualTo(-1));
120 }
121
122 {
123 LSL_List srcWithConstants
124 = new LSL_List(new LSL_Integer(3), ScriptBaseClass.AGENT, ScriptBaseClass.OS_NPC_LAND_AT_TARGET);
125
126 // Test for constants that appears in the source list that should be found
127 int result
128 = m_lslApi.llListFindList(srcWithConstants, new LSL_List(new LSL_Integer(1), new LSL_Integer(2)));
129
130 Assert.That(result, Is.EqualTo(1));
131 }
132 }
133 }
134 } \ No newline at end of file