aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1602
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs40
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs439
-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.cs139
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs64
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs56
-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/ScriptException.cs (renamed from OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs)29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiListTests.cs134
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs70
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs184
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs57
18 files changed, 1961 insertions, 1014 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 82de06f..3bbdbe8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -59,6 +59,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
59using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 59using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
60using PrimType = OpenSim.Region.Framework.Scenes.PrimType; 60using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
61using AssetLandmark = OpenSim.Framework.AssetLandmark; 61using AssetLandmark = OpenSim.Framework.AssetLandmark;
62using RegionFlags = OpenSim.Framework.RegionFlags;
62 63
63using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 64using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
64using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 65using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
@@ -112,6 +113,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
113 new Dictionary<UUID, UserInfoCacheEntry>(); 114 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
116 protected ISoundModule m_SoundModule = null;
115 117
116// protected Timer m_ShoutSayTimer; 118// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0; 119 protected int m_SayShoutCount = 0;
@@ -159,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
159 m_TransferModule = 161 m_TransferModule =
160 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 162 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
161 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 163 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
164 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>();
162 165
163 AsyncCommands = new AsyncCommandManager(ScriptEngine); 166 AsyncCommands = new AsyncCommandManager(ScriptEngine);
164 } 167 }
@@ -341,7 +344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
341 return GetLinkParts(m_host, linkType); 344 return GetLinkParts(m_host, linkType);
342 } 345 }
343 346
344 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 347 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
345 { 348 {
346 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 349 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -426,12 +429,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
426 return key; 429 return key;
427 } 430 }
428 431
429 // convert a LSL_Rotation to a Quaternion 432 /// <summary>
430 public static Quaternion Rot2Quaternion(LSL_Rotation r) 433 /// Return the UUID of the asset matching the specified key or name
434 /// and asset type.
435 /// </summary>
436 /// <param name="k"></param>
437 /// <param name="type"></param>
438 /// <returns></returns>
439 protected UUID KeyOrName(string k, AssetType type)
431 { 440 {
432 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); 441 UUID key;
433 q.Normalize(); 442
434 return q; 443 if (!UUID.TryParse(k, out key))
444 {
445 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
446 if (item != null && item.Type == (int)type)
447 key = item.AssetID;
448 }
449 else
450 {
451 lock (m_host.TaskInventory)
452 {
453 foreach (KeyValuePair<UUID, TaskInventoryItem> item in m_host.TaskInventory)
454 {
455 if (item.Value.Type == (int)type && item.Value.Name == k)
456 {
457 key = item.Value.ItemID;
458 break;
459 }
460 }
461 }
462 }
463
464
465 return key;
435 } 466 }
436 467
437 //These are the implementations of the various ll-functions used by the LSL scripts. 468 //These are the implementations of the various ll-functions used by the LSL scripts.
@@ -1240,9 +1271,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1240 public LSL_Float llGround(LSL_Vector offset) 1271 public LSL_Float llGround(LSL_Vector offset)
1241 { 1272 {
1242 m_host.AddScriptLPS(1); 1273 m_host.AddScriptLPS(1);
1243 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 1274 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
1244 (float)offset.y,
1245 (float)offset.z);
1246 1275
1247 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 1276 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
1248 LSL_Vector vsn = llGroundNormal(offset); 1277 LSL_Vector vsn = llGroundNormal(offset);
@@ -1492,31 +1521,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 if (part == null || part.ParentGroup.IsDeleted) 1521 if (part == null || part.ParentGroup.IsDeleted)
1493 return; 1522 return;
1494 1523
1495 if (scale.x < 0.01) 1524 // 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; 1525 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1503
1504 if (pa != null && pa.IsPhysical) 1526 if (pa != null && pa.IsPhysical)
1505 { 1527 {
1506 if (scale.x > World.m_maxPhys) 1528 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1507 scale.x = World.m_maxPhys; 1529 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1508 if (scale.y > World.m_maxPhys) 1530 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1509 scale.y = World.m_maxPhys; 1531 }
1510 if (scale.z > World.m_maxPhys) 1532 else
1511 scale.z = World.m_maxPhys; 1533 {
1534 // If not physical, then we clamp the scale to the non-physical min/max
1535 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1536 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1537 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1512 } 1538 }
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 1539
1521 Vector3 tmp = part.Scale; 1540 Vector3 tmp = part.Scale;
1522 tmp.X = (float)scale.x; 1541 tmp.X = (float)scale.x;
@@ -1590,7 +1609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1590 if (face == ScriptBaseClass.ALL_SIDES) 1609 if (face == ScriptBaseClass.ALL_SIDES)
1591 face = SceneObjectPart.ALL_SIDES; 1610 face = SceneObjectPart.ALL_SIDES;
1592 1611
1593 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 1612 m_host.SetFaceColorAlpha(face, color, null);
1594 } 1613 }
1595 1614
1596 public void SetTexGen(SceneObjectPart part, int face,int style) 1615 public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -2202,7 +2221,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. 2221 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. 2222 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. 2223 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 2224 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2206 ) 2225 )
2207 ) 2226 )
2208 { 2227 {
@@ -2213,14 +2232,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. 2232 // 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 2233
2215 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; 2234 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
2216 LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); 2235 LandData here = World.GetLandData(objectPos);
2217 LandData there = World.GetLandData((float)pos.x, (float)pos.y); 2236 LandData there = World.GetLandData(pos);
2218 2237
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. 2238 // 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 2239
2221 bool sameParcel = here.GlobalID == there.GlobalID; 2240 bool sameParcel = here.GlobalID == there.GlobalID;
2222 2241
2223 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2242 if (!sameParcel && !World.Permissions.CanRezObject(
2243 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
2224 { 2244 {
2225 return 0; 2245 return 0;
2226 } 2246 }
@@ -2279,16 +2299,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 if (part.ParentGroup.RootPart == part) 2299 if (part.ParentGroup.RootPart == part)
2280 { 2300 {
2281 SceneObjectGroup parent = part.ParentGroup; 2301 SceneObjectGroup parent = part.ParentGroup;
2282 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2302 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2283 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2284 return; 2303 return;
2285 Util.FireAndForget(delegate(object x) { 2304 Util.FireAndForget(delegate(object x) {
2286 parent.UpdateGroupPosition(dest); 2305 parent.UpdateGroupPosition((Vector3)toPos);
2287 }); 2306 });
2288 } 2307 }
2289 else 2308 else
2290 { 2309 {
2291 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2310 part.OffsetPosition = (Vector3)toPos;
2292 SceneObjectGroup parent = part.ParentGroup; 2311 SceneObjectGroup parent = part.ParentGroup;
2293 parent.HasGroupChanged = true; 2312 parent.HasGroupChanged = true;
2294 parent.ScheduleGroupForTerseUpdate(); 2313 parent.ScheduleGroupForTerseUpdate();
@@ -2298,8 +2317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2298 public LSL_Vector llGetPos() 2317 public LSL_Vector llGetPos()
2299 { 2318 {
2300 m_host.AddScriptLPS(1); 2319 m_host.AddScriptLPS(1);
2301 Vector3 pos = m_host.GetWorldPosition(); 2320 return m_host.GetWorldPosition();
2302 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2303 } 2321 }
2304 2322
2305 public LSL_Vector llGetLocalPos() 2323 public LSL_Vector llGetLocalPos()
@@ -2326,7 +2344,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2326 pos = part.AbsolutePosition; 2344 pos = part.AbsolutePosition;
2327 } 2345 }
2328 2346
2329 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2347// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2348
2349 return new LSL_Vector(pos);
2330 } 2350 }
2331 2351
2332 public void llSetRot(LSL_Rotation rot) 2352 public void llSetRot(LSL_Rotation rot)
@@ -2334,26 +2354,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2334 m_host.AddScriptLPS(1); 2354 m_host.AddScriptLPS(1);
2335 2355
2336 // try to let this work as in SL... 2356 // try to let this work as in SL...
2337 if (m_host.LinkNum < 2) 2357 if (m_host.ParentID == 0)
2338 { 2358 {
2339 // Special case: If we are root, rotate complete SOG to new 2359 // special case: If we are root, rotate complete SOG to new rotation
2340 // rotation. 2360 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 } 2361 }
2348 else 2362 else
2349 { 2363 {
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. 2364 // 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; 2365 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2352 if (m_host.ParentGroup != null) // better safe than sorry 2366 if (rootPart != null) // better safe than sorry
2353 { 2367 {
2354 rootPart = m_host.ParentGroup.RootPart; 2368 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2355 if (rootPart != null)
2356 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2357 } 2369 }
2358 } 2370 }
2359 2371
@@ -2363,8 +2375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 public void llSetLocalRot(LSL_Rotation rot) 2375 public void llSetLocalRot(LSL_Rotation rot)
2364 { 2376 {
2365 m_host.AddScriptLPS(1); 2377 m_host.AddScriptLPS(1);
2366 2378 SetRot(m_host, rot);
2367 SetRot(m_host, Rot2Quaternion(rot));
2368 ScriptSleep(200); 2379 ScriptSleep(200);
2369 } 2380 }
2370 2381
@@ -2476,7 +2487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2476 if (local != 0) 2487 if (local != 0)
2477 force *= llGetRot(); 2488 force *= llGetRot();
2478 2489
2479 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2490 m_host.ParentGroup.RootPart.SetForce(force);
2480 } 2491 }
2481 } 2492 }
2482 2493
@@ -2488,10 +2499,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2488 2499
2489 if (!m_host.ParentGroup.IsDeleted) 2500 if (!m_host.ParentGroup.IsDeleted)
2490 { 2501 {
2491 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2502 force = m_host.ParentGroup.RootPart.GetForce();
2492 force.x = tmpForce.X;
2493 force.y = tmpForce.Y;
2494 force.z = tmpForce.Z;
2495 } 2503 }
2496 2504
2497 return force; 2505 return force;
@@ -2500,8 +2508,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 public LSL_Integer llTarget(LSL_Vector position, double range) 2508 public LSL_Integer llTarget(LSL_Vector position, double range)
2501 { 2509 {
2502 m_host.AddScriptLPS(1); 2510 m_host.AddScriptLPS(1);
2503 return m_host.ParentGroup.registerTargetWaypoint( 2511 return m_host.ParentGroup.registerTargetWaypoint(position,
2504 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2512 (float)range);
2505 } 2513 }
2506 2514
2507 public void llTargetRemove(int number) 2515 public void llTargetRemove(int number)
@@ -2513,8 +2521,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2521 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2514 { 2522 {
2515 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2516 return m_host.ParentGroup.registerRotTargetWaypoint( 2524 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 } 2525 }
2519 2526
2520 public void llRotTargetRemove(int number) 2527 public void llRotTargetRemove(int number)
@@ -2526,7 +2533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2526 public void llMoveToTarget(LSL_Vector target, double tau) 2533 public void llMoveToTarget(LSL_Vector target, double tau)
2527 { 2534 {
2528 m_host.AddScriptLPS(1); 2535 m_host.AddScriptLPS(1);
2529 m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); 2536 m_host.MoveToTarget(target, (float)tau);
2530 } 2537 }
2531 2538
2532 public void llStopMoveToTarget() 2539 public void llStopMoveToTarget()
@@ -2539,7 +2546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2539 { 2546 {
2540 m_host.AddScriptLPS(1); 2547 m_host.AddScriptLPS(1);
2541 //No energy force yet 2548 //No energy force yet
2542 Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z); 2549 Vector3 v = force;
2543 if (v.Length() > 20000.0f) 2550 if (v.Length() > 20000.0f)
2544 { 2551 {
2545 v.Normalize(); 2552 v.Normalize();
@@ -2552,13 +2559,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2552 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2559 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2553 { 2560 {
2554 m_host.AddScriptLPS(1); 2561 m_host.AddScriptLPS(1);
2555 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2562 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2556 } 2563 }
2557 2564
2558 public void llSetTorque(LSL_Vector torque, int local) 2565 public void llSetTorque(LSL_Vector torque, int local)
2559 { 2566 {
2560 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2561 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2568 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2562 } 2569 }
2563 2570
2564 public LSL_Vector llGetTorque() 2571 public LSL_Vector llGetTorque()
@@ -2668,63 +2675,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2668 m_host.AddScriptLPS(1); 2675 m_host.AddScriptLPS(1);
2669 2676
2670 // send the sound, once, to all clients in range 2677 // send the sound, once, to all clients in range
2671 m_host.SendSound(KeyOrName(sound).ToString(), volume, false, 0, 0, false, false); 2678 if (m_SoundModule != null)
2679 {
2680 m_SoundModule.SendSound(m_host.UUID,
2681 KeyOrName(sound, AssetType.Sound), volume, false, 0,
2682 0, false, false);
2683 }
2672 } 2684 }
2673 2685
2674 // Xantor 20080528 we should do this differently.
2675 // 1) apply the sound to the object
2676 // 2) schedule full update
2677 // just sending the sound out once doesn't work so well when other avatars come in view later on
2678 // or when the prim gets moved, changed, sat on, whatever
2679 // see large number of mantises (mantes?)
2680 // 20080530 Updated to remove code duplication
2681 // 20080530 Stop sound if there is one, otherwise volume only changes don't work
2682 public void llLoopSound(string sound, double volume) 2686 public void llLoopSound(string sound, double volume)
2683 { 2687 {
2684 m_host.AddScriptLPS(1); 2688 m_host.AddScriptLPS(1);
2685 2689 if (m_SoundModule != null)
2686 if (m_host.Sound != UUID.Zero) 2690 {
2687 llStopSound(); 2691 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound),
2688 2692 volume, 20, false);
2689 m_host.Sound = KeyOrName(sound); 2693 }
2690 m_host.SoundGain = volume;
2691 m_host.SoundFlags = 1; // looping
2692 m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
2693
2694 m_host.ScheduleFullUpdate();
2695 m_host.SendFullUpdateToAllClients();
2696 } 2694 }
2697 2695
2698 public void llLoopSoundMaster(string sound, double volume) 2696 public void llLoopSoundMaster(string sound, double volume)
2699 { 2697 {
2700 m_host.AddScriptLPS(1); 2698 m_host.AddScriptLPS(1);
2701 m_host.ParentGroup.LoopSoundMasterPrim = m_host; 2699 if (m_SoundModule != null)
2702 lock (m_host.ParentGroup.LoopSoundSlavePrims)
2703 { 2700 {
2704 foreach (SceneObjectPart prim in m_host.ParentGroup.LoopSoundSlavePrims) 2701 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound),
2705 { 2702 volume, 20, true);
2706 if (prim.Sound != UUID.Zero)
2707 llStopSound();
2708
2709 prim.Sound = KeyOrName(sound);
2710 prim.SoundGain = volume;
2711 prim.SoundFlags = 1; // looping
2712 prim.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
2713
2714 prim.ScheduleFullUpdate();
2715 prim.SendFullUpdateToAllClients();
2716 }
2717 } 2703 }
2718 if (m_host.Sound != UUID.Zero)
2719 llStopSound();
2720
2721 m_host.Sound = KeyOrName(sound);
2722 m_host.SoundGain = volume;
2723 m_host.SoundFlags = 1; // looping
2724 m_host.SoundRadius = 20; // Magic number, 20 seems reasonable. Make configurable?
2725
2726 m_host.ScheduleFullUpdate();
2727 m_host.SendFullUpdateToAllClients();
2728 } 2704 }
2729 2705
2730 public void llLoopSoundSlave(string sound, double volume) 2706 public void llLoopSoundSlave(string sound, double volume)
@@ -2741,61 +2717,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2741 m_host.AddScriptLPS(1); 2717 m_host.AddScriptLPS(1);
2742 2718
2743 // send the sound, once, to all clients in range 2719 // send the sound, once, to all clients in range
2744 m_host.SendSound(KeyOrName(sound).ToString(), volume, false, 0, 0, true, false); 2720 if (m_SoundModule != null)
2721 {
2722 m_SoundModule.SendSound(m_host.UUID,
2723 KeyOrName(sound, AssetType.Sound), volume, false, 0,
2724 0, true, false);
2725 }
2745 } 2726 }
2746 2727
2747 public void llTriggerSound(string sound, double volume) 2728 public void llTriggerSound(string sound, double volume)
2748 { 2729 {
2749 m_host.AddScriptLPS(1); 2730 m_host.AddScriptLPS(1);
2750 // send the sound, once, to all clients in range 2731 // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory.
2751 m_host.SendSound(KeyOrName(sound).ToString(), volume, true, 0, 0, false, false); 2732 if (m_SoundModule != null)
2733 {
2734 m_SoundModule.SendSound(m_host.UUID,
2735 KeyOrName(sound, AssetType.Sound), volume, true, 0, 0,
2736 false, false);
2737 }
2752 } 2738 }
2753 2739
2754 // Xantor 20080528: Clear prim data of sound instead
2755 public void llStopSound() 2740 public void llStopSound()
2756 { 2741 {
2757 m_host.AddScriptLPS(1); 2742 m_host.AddScriptLPS(1);
2758 if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host)) 2743
2759 { 2744 if (m_SoundModule != null)
2760 if (m_host.ParentGroup.LoopSoundMasterPrim == m_host) 2745 m_SoundModule.StopSound(m_host.UUID);
2761 {
2762 foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims)
2763 {
2764 part.Sound = UUID.Zero;
2765 part.SoundGain = 0;
2766 part.SoundFlags = 0;
2767 part.SoundRadius = 0;
2768 part.ScheduleFullUpdate();
2769 part.SendFullUpdateToAllClients();
2770 }
2771 m_host.ParentGroup.LoopSoundMasterPrim = null;
2772 m_host.ParentGroup.LoopSoundSlavePrims.Clear();
2773 }
2774 else
2775 {
2776 m_host.Sound = UUID.Zero;
2777 m_host.SoundGain = 0;
2778 m_host.SoundFlags = 0;
2779 m_host.SoundRadius = 0;
2780 m_host.ScheduleFullUpdate();
2781 m_host.SendFullUpdateToAllClients();
2782 }
2783 }
2784 else
2785 {
2786 m_host.Sound = UUID.Zero;
2787 m_host.SoundGain = 0;
2788 m_host.SoundFlags = 0;
2789 m_host.SoundRadius = 0;
2790 m_host.ScheduleFullUpdate();
2791 m_host.SendFullUpdateToAllClients();
2792 }
2793 } 2746 }
2794 2747
2795 public void llPreloadSound(string sound) 2748 public void llPreloadSound(string sound)
2796 { 2749 {
2797 m_host.AddScriptLPS(1); 2750 m_host.AddScriptLPS(1);
2798 m_host.PreloadSound(sound); 2751 if (m_SoundModule != null)
2752 m_SoundModule.PreloadSound(m_host.UUID, KeyOrName(sound), 0);
2799 ScriptSleep(1000); 2753 ScriptSleep(1000);
2800 } 2754 }
2801 2755
@@ -3123,13 +3077,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 return; 3077 return;
3124 } 3078 }
3125 3079
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 3080 // need the magnitude later
3130 // float velmag = (float)Util.GetMagnitude(llvel); 3081 // float velmag = (float)Util.GetMagnitude(llvel);
3131 3082
3132 SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); 3083 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
3133 3084
3134 // If either of these are null, then there was an unknown error. 3085 // If either of these are null, then there was an unknown error.
3135 if (new_group == null) 3086 if (new_group == null)
@@ -3156,11 +3107,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 3107
3157 PhysicsActor pa = new_group.RootPart.PhysActor; 3108 PhysicsActor pa = new_group.RootPart.PhysActor;
3158 3109
3159 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3110 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3160 { 3111 {
3161 float groupmass = new_group.GetMass(); 3112 float groupmass = new_group.GetMass();
3162 llvel *= -groupmass; 3113 vel *= -groupmass;
3163 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0); 3114 llApplyImpulse(vel, 0);
3164 } 3115 }
3165 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3116 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3166 return; 3117 return;
@@ -3211,7 +3162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3211 return; 3162 return;
3212 } 3163 }
3213 3164
3214 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); 3165 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3215 } 3166 }
3216 } 3167 }
3217 3168
@@ -3637,7 +3588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 } 3588 }
3638 else 3589 else
3639 { 3590 {
3640 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); 3591 m_host.RotLookAt(target, (float)strength, (float)damping);
3641 } 3592 }
3642 } 3593 }
3643 3594
@@ -3718,7 +3669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 3669
3719 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3670 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3720 { 3671 {
3721 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3672 part.UpdateAngularVelocity(axis * spinrate);
3722 } 3673 }
3723 3674
3724 public LSL_Integer llGetStartParameter() 3675 public LSL_Integer llGetStartParameter()
@@ -3932,7 +3883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 try 3883 try
3933 { 3884 {
3934 foreach (SceneObjectPart part in parts) 3885 foreach (SceneObjectPart part in parts)
3935 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3886 part.SetFaceColorAlpha(face, color, null);
3936 } 3887 }
3937 finally 3888 finally
3938 { 3889 {
@@ -4158,6 +4109,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4158 } 4109 }
4159 4110
4160 /// <summary> 4111 /// <summary>
4112 /// Returns the name of the child prim or seated avatar matching the
4113 /// specified link number.
4114 /// </summary>
4115 /// <param name="linknum">
4116 /// The number of a link in the linkset or a link-related constant.
4117 /// </param>
4118 /// <returns>
4119 /// The name determined to match the specified link number.
4120 /// </returns>
4121 /// <remarks>
4161 /// The rules governing the returned name are not simple. The only 4122 /// The rules governing the returned name are not simple. The only
4162 /// time a blank name is returned is if the target prim has a blank 4123 /// time a blank name is returned is if the target prim has a blank
4163 /// name. If no prim with the given link number can be found then 4124 /// name. If no prim with the given link number can be found then
@@ -4185,10 +4146,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4185 /// Mentions NULL_KEY being returned 4146 /// Mentions NULL_KEY being returned
4186 /// http://wiki.secondlife.com/wiki/LlGetLinkName 4147 /// http://wiki.secondlife.com/wiki/LlGetLinkName
4187 /// Mentions using the LINK_* constants, some of which are negative 4148 /// Mentions using the LINK_* constants, some of which are negative
4188 /// </summary> 4149 /// </remarks>
4189 public LSL_String llGetLinkName(int linknum) 4150 public LSL_String llGetLinkName(int linknum)
4190 { 4151 {
4191 m_host.AddScriptLPS(1); 4152 m_host.AddScriptLPS(1);
4153 // simplest case, this prims link number
4154 if (linknum == m_host.LinkNum || linknum == ScriptBaseClass.LINK_THIS)
4155 return m_host.Name;
4156
4192 // parse for sitting avatare-names 4157 // parse for sitting avatare-names
4193 List<String> nametable = new List<String>(); 4158 List<String> nametable = new List<String>();
4194 World.ForEachRootScenePresence(delegate(ScenePresence presence) 4159 World.ForEachRootScenePresence(delegate(ScenePresence presence)
@@ -4212,10 +4177,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4212 return nametable[totalprims - linknum]; 4177 return nametable[totalprims - linknum];
4213 } 4178 }
4214 4179
4215 // simplest case, this prims link number
4216 if (m_host.LinkNum == linknum)
4217 return m_host.Name;
4218
4219 // Single prim 4180 // Single prim
4220 if (m_host.LinkNum == 0) 4181 if (m_host.LinkNum == 0)
4221 { 4182 {
@@ -4364,7 +4325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4364 World.RegionInfo.RegionName+" "+ 4325 World.RegionInfo.RegionName+" "+
4365 m_host.AbsolutePosition.ToString(), 4326 m_host.AbsolutePosition.ToString(),
4366 agentItem.ID, true, m_host.AbsolutePosition, 4327 agentItem.ID, true, m_host.AbsolutePosition,
4367 bucket); 4328 bucket, true);
4368 4329
4369 ScenePresence sp; 4330 ScenePresence sp;
4370 4331
@@ -4402,9 +4363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4402 public void llSetText(string text, LSL_Vector color, double alpha) 4363 public void llSetText(string text, LSL_Vector color, double alpha)
4403 { 4364 {
4404 m_host.AddScriptLPS(1); 4365 m_host.AddScriptLPS(1);
4405 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4366 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4406 Util.Clip((float)color.y, 0.0f, 1.0f),
4407 Util.Clip((float)color.z, 0.0f, 1.0f));
4408 if (text.Length > 254) 4367 if (text.Length > 254)
4409 text = text.Remove(254); 4368 text = text.Remove(254);
4410 4369
@@ -4631,14 +4590,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4631 ScriptSleep(5000); 4590 ScriptSleep(5000);
4632 } 4591 }
4633 4592
4634 public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) 4593 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4635 { 4594 {
4636 m_host.AddScriptLPS(1); 4595 m_host.AddScriptLPS(1);
4637 UUID agentId = new UUID(); 4596 UUID agentId = new UUID();
4638 4597
4639 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4640 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4641
4642 if (UUID.TryParse(agent, out agentId)) 4598 if (UUID.TryParse(agent, out agentId))
4643 { 4599 {
4644 ScenePresence presence = World.GetScenePresence(agentId); 4600 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4667,15 +4623,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4667 } 4623 }
4668 } 4624 }
4669 4625
4670 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) 4626 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4671 { 4627 {
4672 m_host.AddScriptLPS(1); 4628 m_host.AddScriptLPS(1);
4673 UUID agentId = new UUID(); 4629 UUID agentId = new UUID();
4674 4630
4675 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4631 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
4676 4632
4677 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4678 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4679 if (UUID.TryParse(agent, out agentId)) 4633 if (UUID.TryParse(agent, out agentId))
4680 { 4634 {
4681 ScenePresence presence = World.GetScenePresence(agentId); 4635 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4777,16 +4731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4777 return; 4731 return;
4778 } 4732 }
4779 // TODO: Parameter check logic required. 4733 // TODO: Parameter check logic required.
4780 UUID soundId = UUID.Zero; 4734 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4781 if (!UUID.TryParse(impact_sound, out soundId))
4782 {
4783 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(impact_sound);
4784
4785 if (item != null && item.Type == (int)AssetType.Sound)
4786 soundId = item.AssetID;
4787 }
4788
4789 m_host.CollisionSound = soundId;
4790 m_host.CollisionSoundVolume = (float)impact_volume; 4735 m_host.CollisionSoundVolume = (float)impact_volume;
4791 m_host.CollisionSoundType = 1; 4736 m_host.CollisionSoundType = 1;
4792 } 4737 }
@@ -4972,7 +4917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4972 distance_attenuation = 1f / normalized_units; 4917 distance_attenuation = 1f / normalized_units;
4973 } 4918 }
4974 4919
4975 Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); 4920 Vector3 applied_linear_impulse = impulse;
4976 { 4921 {
4977 float impulse_length = applied_linear_impulse.Length(); 4922 float impulse_length = applied_linear_impulse.Length();
4978 4923
@@ -5620,25 +5565,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5620 /// separated list. There is a space after 5565 /// separated list. There is a space after
5621 /// each comma. 5566 /// each comma.
5622 /// </summary> 5567 /// </summary>
5623
5624 public LSL_String llList2CSV(LSL_List src) 5568 public LSL_String llList2CSV(LSL_List src)
5625 { 5569 {
5626
5627 string ret = String.Empty;
5628 int x = 0;
5629
5630 m_host.AddScriptLPS(1); 5570 m_host.AddScriptLPS(1);
5631 5571
5632 if (src.Data.Length > 0) 5572 return string.Join(", ",
5633 { 5573 (new List<object>(src.Data)).ConvertAll<string>(o =>
5634 ret = src.Data[x++].ToString(); 5574 {
5635 for (; x < src.Data.Length; x++) 5575 return o.ToString();
5636 { 5576 }).ToArray());
5637 ret += ", "+src.Data[x].ToString();
5638 }
5639 }
5640
5641 return ret;
5642 } 5577 }
5643 5578
5644 /// <summary> 5579 /// <summary>
@@ -5937,27 +5872,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5937 /// Returns the index of the first occurrence of test 5872 /// Returns the index of the first occurrence of test
5938 /// in src. 5873 /// in src.
5939 /// </summary> 5874 /// </summary>
5940 5875 /// <param name="src">Source list</param>
5876 /// <param name="test">List to search for</param>
5877 /// <returns>
5878 /// The index number of the point in src where test was found if it was found.
5879 /// Otherwise returns -1
5880 /// </returns>
5941 public LSL_Integer llListFindList(LSL_List src, LSL_List test) 5881 public LSL_Integer llListFindList(LSL_List src, LSL_List test)
5942 { 5882 {
5943
5944 int index = -1; 5883 int index = -1;
5945 int length = src.Length - test.Length + 1; 5884 int length = src.Length - test.Length + 1;
5946 5885
5947 m_host.AddScriptLPS(1); 5886 m_host.AddScriptLPS(1);
5948 5887
5949 // If either list is empty, do not match 5888 // If either list is empty, do not match
5950
5951 if (src.Length != 0 && test.Length != 0) 5889 if (src.Length != 0 && test.Length != 0)
5952 { 5890 {
5953 for (int i = 0; i < length; i++) 5891 for (int i = 0; i < length; i++)
5954 { 5892 {
5955 if (src.Data[i].Equals(test.Data[0])) 5893 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
5894 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
5895 // and so the comparison fails even if the LSL_Integer conceptually has the same value.
5896 // Therefore, here we test Equals on both the source and destination objects.
5897 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5898 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))
5956 { 5899 {
5957 int j; 5900 int j;
5958 for (j = 1; j < test.Length; j++) 5901 for (j = 1; j < test.Length; j++)
5959 if (!src.Data[i+j].Equals(test.Data[j])) 5902 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))
5960 break; 5903 break;
5904
5961 if (j == test.Length) 5905 if (j == test.Length)
5962 { 5906 {
5963 index = i; 5907 index = i;
@@ -5968,19 +5912,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5968 } 5912 }
5969 5913
5970 return index; 5914 return index;
5971
5972 } 5915 }
5973 5916
5974 public LSL_String llGetObjectName() 5917 public LSL_String llGetObjectName()
5975 { 5918 {
5976 m_host.AddScriptLPS(1); 5919 m_host.AddScriptLPS(1);
5977 return m_host.Name!=null?m_host.Name:String.Empty; 5920 return m_host.Name !=null ? m_host.Name : String.Empty;
5978 } 5921 }
5979 5922
5980 public void llSetObjectName(string name) 5923 public void llSetObjectName(string name)
5981 { 5924 {
5982 m_host.AddScriptLPS(1); 5925 m_host.AddScriptLPS(1);
5983 m_host.Name = name!=null?name:String.Empty; 5926 m_host.Name = name != null ? name : String.Empty;
5984 } 5927 }
5985 5928
5986 public LSL_String llGetDate() 5929 public LSL_String llGetDate()
@@ -6154,7 +6097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6154 flags |= ScriptBaseClass.AGENT_SITTING; 6097 flags |= ScriptBaseClass.AGENT_SITTING;
6155 } 6098 }
6156 6099
6157 if (agent.Animator.Animations.DefaultAnimation.AnimID 6100 if (agent.Animator.Animations.ImplicitDefaultAnimation.AnimID
6158 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 6101 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
6159 { 6102 {
6160 flags |= ScriptBaseClass.AGENT_SITTING; 6103 flags |= ScriptBaseClass.AGENT_SITTING;
@@ -6311,19 +6254,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6311 m_host.AddScriptLPS(1); 6254 m_host.AddScriptLPS(1);
6312 6255
6313 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6256 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6314 if (parts.Count > 0) 6257
6258 try
6315 { 6259 {
6316 try 6260 foreach (SceneObjectPart part in parts)
6317 {
6318 foreach (var part in parts)
6319 {
6320 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6321 }
6322 }
6323 finally
6324 { 6261 {
6262 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6325 } 6263 }
6326 } 6264 }
6265 finally
6266 {
6267 }
6327 } 6268 }
6328 6269
6329 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 6270 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
@@ -6352,10 +6293,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6352 LSL_Vector bottom_south_west) 6293 LSL_Vector bottom_south_west)
6353 { 6294 {
6354 m_host.AddScriptLPS(1); 6295 m_host.AddScriptLPS(1);
6355 float radius1 = (float)llVecDist(llGetPos(), top_north_east); 6296 if (m_SoundModule != null)
6356 float radius2 = (float)llVecDist(llGetPos(), bottom_south_west); 6297 {
6357 float radius = Math.Abs(radius1 - radius2); 6298 m_SoundModule.TriggerSoundLimited(m_host.UUID,
6358 m_host.SendSound(KeyOrName(sound).ToString(), volume, true, 0, radius, false, false); 6299 KeyOrName(sound, AssetType.Sound), volume,
6300 bottom_south_west, top_north_east);
6301 }
6359 } 6302 }
6360 6303
6361 public void llEjectFromLand(string pest) 6304 public void llEjectFromLand(string pest)
@@ -6541,9 +6484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6541 6484
6542 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6485 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6543 //the height of that point on the plane. The resulting vector gives the slope. 6486 //the height of that point on the plane. The resulting vector gives the slope.
6544 Vector3 vsl = new Vector3(); 6487 Vector3 vsl = vsn;
6545 vsl.X = (float)vsn.x;
6546 vsl.Y = (float)vsn.y;
6547 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6488 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6548 vsl.Normalize(); 6489 vsl.Normalize();
6549 //Normalization might be overkill here 6490 //Normalization might be overkill here
@@ -6554,9 +6495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6554 public LSL_Vector llGroundNormal(LSL_Vector offset) 6495 public LSL_Vector llGroundNormal(LSL_Vector offset)
6555 { 6496 {
6556 m_host.AddScriptLPS(1); 6497 m_host.AddScriptLPS(1);
6557 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 6498 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6558 (float)offset.y,
6559 (float)offset.z);
6560 // Clamp to valid position 6499 // Clamp to valid position
6561 if (pos.X < 0) 6500 if (pos.X < 0)
6562 pos.X = 0; 6501 pos.X = 0;
@@ -6721,7 +6660,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6721 6660
6722 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6661 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6723 6662
6724 foreach (var part in parts) 6663 foreach (SceneObjectPart part in parts)
6725 { 6664 {
6726 SetParticleSystem(part, rules); 6665 SetParticleSystem(part, rules);
6727 } 6666 }
@@ -6965,16 +6904,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6965 if (m_TransferModule != null) 6904 if (m_TransferModule != null)
6966 { 6905 {
6967 byte[] bucket = new byte[] { (byte)AssetType.Folder }; 6906 byte[] bucket = new byte[] { (byte)AssetType.Folder };
6968 6907
6908 Vector3 pos = m_host.AbsolutePosition;
6909
6969 GridInstantMessage msg = new GridInstantMessage(World, 6910 GridInstantMessage msg = new GridInstantMessage(World,
6970 m_host.UUID, m_host.Name + ", an object owned by " + 6911 m_host.OwnerID, m_host.Name, destID,
6971 resolveName(m_host.OwnerID) + ",", destID,
6972 (byte)InstantMessageDialog.TaskInventoryOffered, 6912 (byte)InstantMessageDialog.TaskInventoryOffered,
6973 false, category + "\n" + m_host.Name + " is located at " + 6913 false, string.Format("'{0}'", category),
6974 World.RegionInfo.RegionName + " " + 6914// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6975 m_host.AbsolutePosition.ToString(), 6915// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6976 folderID, true, m_host.AbsolutePosition, 6916 folderID, false, pos,
6977 bucket); 6917 bucket, false);
6978 6918
6979 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 6919 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
6980 } 6920 }
@@ -7010,8 +6950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7010 6950
7011 if (!m_host.ParentGroup.IsDeleted) 6951 if (!m_host.ParentGroup.IsDeleted)
7012 { 6952 {
7013 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, 6953 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
7014 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
7015 } 6954 }
7016 } 6955 }
7017 6956
@@ -7023,7 +6962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7023 6962
7024 if (!m_host.ParentGroup.IsDeleted) 6963 if (!m_host.ParentGroup.IsDeleted)
7025 { 6964 {
7026 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); 6965 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
7027 } 6966 }
7028 } 6967 }
7029 6968
@@ -7053,8 +6992,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7053 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6992 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7054 rot.s = 1; // ZERO_ROTATION = 0,0,0,1 6993 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7055 6994
7056 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6995 part.SitTargetPosition = offset;
7057 part.SitTargetOrientation = Rot2Quaternion(rot); 6996 part.SitTargetOrientation = rot;
7058 part.ParentGroup.HasGroupChanged = true; 6997 part.ParentGroup.HasGroupChanged = true;
7059 } 6998 }
7060 6999
@@ -7157,13 +7096,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7157 public void llSetCameraEyeOffset(LSL_Vector offset) 7096 public void llSetCameraEyeOffset(LSL_Vector offset)
7158 { 7097 {
7159 m_host.AddScriptLPS(1); 7098 m_host.AddScriptLPS(1);
7160 m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7099 m_host.SetCameraEyeOffset(offset);
7161 } 7100 }
7162 7101
7163 public void llSetCameraAtOffset(LSL_Vector offset) 7102 public void llSetCameraAtOffset(LSL_Vector offset)
7164 { 7103 {
7165 m_host.AddScriptLPS(1); 7104 m_host.AddScriptLPS(1);
7166 m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7105 m_host.SetCameraAtOffset(offset);
7167 } 7106 }
7168 7107
7169 public LSL_String llDumpList2String(LSL_List src, string seperator) 7108 public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -7185,7 +7124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7185 public LSL_Integer llScriptDanger(LSL_Vector pos) 7124 public LSL_Integer llScriptDanger(LSL_Vector pos)
7186 { 7125 {
7187 m_host.AddScriptLPS(1); 7126 m_host.AddScriptLPS(1);
7188 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); 7127 bool result = World.ScriptDanger(m_host.LocalId, pos);
7189 if (result) 7128 if (result)
7190 { 7129 {
7191 return 1; 7130 return 1;
@@ -7767,7 +7706,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7767 { 7706 {
7768 m_host.AddScriptLPS(1); 7707 m_host.AddScriptLPS(1);
7769 7708
7770 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7709 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7771 7710
7772 ScriptSleep(200); 7711 ScriptSleep(200);
7773 } 7712 }
@@ -7776,10 +7715,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 { 7715 {
7777 m_host.AddScriptLPS(1); 7716 m_host.AddScriptLPS(1);
7778 7717
7779 setLinkPrimParams(linknumber, rules); 7718 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7719
7720 ScriptSleep(200);
7780 } 7721 }
7781 7722
7782 private void setLinkPrimParams(int linknumber, LSL_List rules) 7723 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7783 { 7724 {
7784 List<object> parts = new List<object>(); 7725 List<object> parts = new List<object>();
7785 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7726 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7790,15 +7731,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7790 parts.Add(p); 7731 parts.Add(p);
7791 7732
7792 LSL_List remaining = null; 7733 LSL_List remaining = null;
7734 uint rulesParsed = 0;
7793 7735
7794 if (parts.Count > 0) 7736 if (parts.Count > 0)
7795 { 7737 {
7796 foreach (object part in parts) 7738 foreach (object part in parts)
7797 { 7739 {
7798 if (part is SceneObjectPart) 7740 if (part is SceneObjectPart)
7799 remaining = SetPrimParams((SceneObjectPart)part, rules); 7741 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7800 else 7742 else
7801 remaining = SetPrimParams((ScenePresence)part, rules); 7743 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7802 } 7744 }
7803 7745
7804 while ((object)remaining != null && remaining.Length > 2) 7746 while ((object)remaining != null && remaining.Length > 2)
@@ -7817,9 +7759,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7817 foreach (object part in parts) 7759 foreach (object part in parts)
7818 { 7760 {
7819 if (part is SceneObjectPart) 7761 if (part is SceneObjectPart)
7820 remaining = SetPrimParams((SceneObjectPart)part, rules); 7762 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7821 else 7763 else
7822 remaining = SetPrimParams((ScenePresence)part, rules); 7764 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7823 } 7765 }
7824 } 7766 }
7825 } 7767 }
@@ -7857,6 +7799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 7799
7858 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7800 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7859 { 7801 {
7802 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7860 llSetLinkPrimitiveParamsFast(linknumber, rules); 7803 llSetLinkPrimitiveParamsFast(linknumber, rules);
7861 ScriptSleep(200); 7804 ScriptSleep(200);
7862 } 7805 }
@@ -7884,195 +7827,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7884 return new Vector3((float)x, (float)y, (float)z); 7827 return new Vector3((float)x, (float)y, (float)z);
7885 } 7828 }
7886 7829
7887 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 7830 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7888 {
7889 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7890
7891 int idx = 0;
7892
7893 bool positionChanged = false;
7894 Vector3 finalPos = Vector3.Zero;
7895
7896 try
7897 {
7898 while (idx < rules.Length)
7899 {
7900 int code = rules.GetLSLIntegerItem(idx++);
7901
7902 int remain = rules.Length - idx;
7903
7904 switch (code)
7905 {
7906 case (int)ScriptBaseClass.PRIM_POSITION:
7907 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7908 {
7909 if (remain < 1)
7910 return null;
7911
7912 LSL_Vector v;
7913 v = rules.GetVector3Item(idx++);
7914
7915 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7916 if (part == null)
7917 break;
7918
7919 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7920 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7921 if (part.LinkNum > 1)
7922 {
7923 localRot = GetPartLocalRot(part);
7924 localPos = GetPartLocalPos(part);
7925 }
7926
7927 v -= localPos;
7928 v /= localRot;
7929
7930 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7931
7932 v = v + 2 * sitOffset;
7933
7934 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7935 av.SendAvatarDataToAllAgents();
7936
7937 }
7938 break;
7939
7940 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7941 case (int)ScriptBaseClass.PRIM_ROTATION:
7942 {
7943 if (remain < 1)
7944 return null;
7945
7946 LSL_Rotation r;
7947 r = rules.GetQuaternionItem(idx++);
7948
7949 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7950 if (part == null)
7951 break;
7952
7953 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7954 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7955
7956 if (part.LinkNum > 1)
7957 localRot = GetPartLocalRot(part);
7958
7959 r = r * llGetRootRotation() / localRot;
7960 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7961 av.SendAvatarDataToAllAgents();
7962 }
7963 break;
7964
7965 // parse rest doing nothing but number of parameters error check
7966 case (int)ScriptBaseClass.PRIM_SIZE:
7967 case (int)ScriptBaseClass.PRIM_MATERIAL:
7968 case (int)ScriptBaseClass.PRIM_PHANTOM:
7969 case (int)ScriptBaseClass.PRIM_PHYSICS:
7970 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7971 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7972 case (int)ScriptBaseClass.PRIM_NAME:
7973 case (int)ScriptBaseClass.PRIM_DESC:
7974 if (remain < 1)
7975 return null;
7976 idx++;
7977 break;
7978
7979 case (int)ScriptBaseClass.PRIM_GLOW:
7980 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7981 case (int)ScriptBaseClass.PRIM_TEXGEN:
7982 if (remain < 2)
7983 return null;
7984 idx += 2;
7985 break;
7986
7987 case (int)ScriptBaseClass.PRIM_TYPE:
7988 if (remain < 3)
7989 return null;
7990 code = (int)rules.GetLSLIntegerItem(idx++);
7991 remain = rules.Length - idx;
7992 switch (code)
7993 {
7994 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7995 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7996 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7997 if (remain < 6)
7998 return null;
7999 idx += 6;
8000 break;
8001
8002 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
8003 if (remain < 5)
8004 return null;
8005 idx += 5;
8006 break;
8007
8008 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
8009 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
8010 case (int)ScriptBaseClass.PRIM_TYPE_RING:
8011 if (remain < 11)
8012 return null;
8013 idx += 11;
8014 break;
8015
8016 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
8017 if (remain < 2)
8018 return null;
8019 idx += 2;
8020 break;
8021 }
8022 break;
8023
8024 case (int)ScriptBaseClass.PRIM_COLOR:
8025 case (int)ScriptBaseClass.PRIM_TEXT:
8026 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8027 case (int)ScriptBaseClass.PRIM_OMEGA:
8028 if (remain < 3)
8029 return null;
8030 idx += 3;
8031 break;
8032
8033 case (int)ScriptBaseClass.PRIM_TEXTURE:
8034 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8035 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8036 if (remain < 5)
8037 return null;
8038 idx += 5;
8039 break;
8040
8041 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8042 if (remain < 7)
8043 return null;
8044
8045 idx += 7;
8046 break;
8047
8048 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8049 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8050 return null;
8051
8052 return rules.GetSublist(idx, -1);
8053 }
8054 }
8055 }
8056
8057 finally
8058 {
8059 if (positionChanged)
8060 {
8061 av.OffsetPosition = finalPos;
8062// av.SendAvatarDataToAllAgents();
8063 av.SendTerseUpdateToAllClients();
8064 positionChanged = false;
8065 }
8066 }
8067 return null;
8068 }
8069
8070 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
8071 { 7831 {
8072 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7832 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8073 return null; 7833 return null;
8074 7834
8075 int idx = 0; 7835 int idx = 0;
7836 int idxStart = 0;
8076 7837
8077 SceneObjectGroup parentgrp = part.ParentGroup; 7838 SceneObjectGroup parentgrp = part.ParentGroup;
8078 7839
@@ -8083,9 +7844,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8083 { 7844 {
8084 while (idx < rules.Length) 7845 while (idx < rules.Length)
8085 { 7846 {
7847 ++rulesParsed;
8086 int code = rules.GetLSLIntegerItem(idx++); 7848 int code = rules.GetLSLIntegerItem(idx++);
8087 7849
8088 int remain = rules.Length - idx; 7850 int remain = rules.Length - idx;
7851 idxStart = idx;
8089 7852
8090 int face; 7853 int face;
8091 LSL_Vector v; 7854 LSL_Vector v;
@@ -8115,18 +7878,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 return null; 7878 return null;
8116 7879
8117 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7880 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8118 SceneObjectPart rootPart = parentgrp.RootPart;
8119 // try to let this work as in SL... 7881 // try to let this work as in SL...
8120 if (rootPart == part) 7882 if (part.ParentID == 0)
8121 { 7883 {
8122 // special case: If we are root, rotate complete SOG to new rotation 7884 // special case: If we are root, rotate complete SOG to new rotation
8123 SetRot(part, Rot2Quaternion(q)); 7885 SetRot(part, q);
8124 } 7886 }
8125 else 7887 else
8126 { 7888 {
8127 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7889 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
8128 // sounds like sl bug that we need to replicate 7890 SceneObjectPart rootPart = part.ParentGroup.RootPart;
8129 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7891 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
8130 } 7892 }
8131 7893
8132 break; 7894 break;
@@ -8300,8 +8062,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8300 LSL_Vector color=rules.GetVector3Item(idx++); 8062 LSL_Vector color=rules.GetVector3Item(idx++);
8301 double alpha=(double)rules.GetLSLFloatItem(idx++); 8063 double alpha=(double)rules.GetLSLFloatItem(idx++);
8302 8064
8303 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 8065 part.SetFaceColorAlpha(face, color, alpha);
8304 SetAlpha(part, alpha, face);
8305 8066
8306 break; 8067 break;
8307 8068
@@ -8449,9 +8210,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8449 string primText = rules.GetLSLStringItem(idx++); 8210 string primText = rules.GetLSLStringItem(idx++);
8450 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 8211 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
8451 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 8212 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
8452 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 8213 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
8453 Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
8454 Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
8455 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 8214 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
8456 8215
8457 break; 8216 break;
@@ -8470,8 +8229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8470 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8229 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8471 if (remain < 1) 8230 if (remain < 1)
8472 return null; 8231 return null;
8473 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8232 SetRot(part, rules.GetQuaternionItem(idx++));
8474 SetRot(part, Rot2Quaternion(lr));
8475 break; 8233 break;
8476 case (int)ScriptBaseClass.PRIM_OMEGA: 8234 case (int)ScriptBaseClass.PRIM_OMEGA:
8477 if (remain < 3) 8235 if (remain < 3)
@@ -8481,7 +8239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8481 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8239 LSL_Float gain = rules.GetLSLFloatItem(idx++);
8482 TargetOmega(part, axis, (double)spinrate, (double)gain); 8240 TargetOmega(part, axis, (double)spinrate, (double)gain);
8483 break; 8241 break;
8484 8242 case (int)ScriptBaseClass.PRIM_SLICE:
8243 if (remain < 1)
8244 return null;
8245 LSL_Vector slice = rules.GetVector3Item(idx++);
8246 part.UpdateSlice((float)slice.x, (float)slice.y);
8247 break;
8485 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8248 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8486 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8249 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8487 return null; 8250 return null;
@@ -8490,6 +8253,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8490 } 8253 }
8491 } 8254 }
8492 } 8255 }
8256 catch (InvalidCastException e)
8257 {
8258 ShoutError(string.Format(
8259 "{0} error running rule #{1}: arg #{2} ",
8260 originFunc, rulesParsed, idx - idxStart) + e.Message);
8261 }
8493 finally 8262 finally
8494 { 8263 {
8495 if (positionChanged) 8264 if (positionChanged)
@@ -8498,12 +8267,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8498 { 8267 {
8499 SceneObjectGroup parent = part.ParentGroup; 8268 SceneObjectGroup parent = part.ParentGroup;
8500 Util.FireAndForget(delegate(object x) { 8269 Util.FireAndForget(delegate(object x) {
8501 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8270 parent.UpdateGroupPosition(currentPosition);
8502 }); 8271 });
8503 } 8272 }
8504 else 8273 else
8505 { 8274 {
8506 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); 8275 part.OffsetPosition = currentPosition;
8507 SceneObjectGroup parent = part.ParentGroup; 8276 SceneObjectGroup parent = part.ParentGroup;
8508 parent.HasGroupChanged = true; 8277 parent.HasGroupChanged = true;
8509 parent.ScheduleGroupForTerseUpdate(); 8278 parent.ScheduleGroupForTerseUpdate();
@@ -8792,7 +8561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8792 // and standing avatar since server 1.36 8561 // and standing avatar since server 1.36
8793 LSL_Vector lower; 8562 LSL_Vector lower;
8794 LSL_Vector upper; 8563 LSL_Vector upper;
8795 if (presence.Animator.Animations.DefaultAnimation.AnimID 8564 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8796 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8565 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8797 { 8566 {
8798 // This is for ground sitting avatars 8567 // This is for ground sitting avatars
@@ -8881,7 +8650,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8881 public LSL_List llGetPrimitiveParams(LSL_List rules) 8650 public LSL_List llGetPrimitiveParams(LSL_List rules)
8882 { 8651 {
8883 m_host.AddScriptLPS(1); 8652 m_host.AddScriptLPS(1);
8884 return GetLinkPrimitiveParams(m_host, rules); 8653
8654 LSL_List result = new LSL_List();
8655
8656 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8657
8658 while (remaining != null && remaining.Length > 2)
8659 {
8660 int linknumber = remaining.GetLSLIntegerItem(0);
8661 rules = remaining.GetSublist(1, -1);
8662 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8663
8664 foreach (SceneObjectPart part in parts)
8665 remaining = GetPrimParams(part, rules, ref result);
8666 }
8667
8668 return result;
8885 } 8669 }
8886 8670
8887 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8671 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -8891,294 +8675,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8891 // acording to SL wiki this must indicate a single link number or link_root or link_this. 8675 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8892 // keep other options as before 8676 // keep other options as before
8893 8677
8894 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8678 List<SceneObjectPart> parts;
8895 List<ScenePresence> avatars = GetLinkAvatars(linknumber); 8679 List<ScenePresence> avatars;
8896 8680
8897 LSL_List res = new LSL_List(); 8681 LSL_List res = new LSL_List();
8682 LSL_List remaining = null;
8898 8683
8899 if (parts.Count > 0) 8684 while (rules.Length > 0)
8900 { 8685 {
8901 foreach (var part in parts) 8686 parts = GetLinkParts(linknumber);
8687 avatars = GetLinkAvatars(linknumber);
8688
8689 remaining = null;
8690 foreach (SceneObjectPart part in parts)
8902 { 8691 {
8903 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8692 remaining = GetPrimParams(part, rules, ref res);
8904 res += partRes;
8905 } 8693 }
8906 }
8907 if (avatars.Count > 0)
8908 {
8909 foreach (ScenePresence avatar in avatars) 8694 foreach (ScenePresence avatar in avatars)
8910 { 8695 {
8911 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules); 8696 remaining = GetPrimParams(avatar, rules, ref res);
8912 res += avaRes;
8913 } 8697 }
8914 }
8915 return res;
8916 }
8917
8918 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8919 {
8920 // avatars case
8921 // replies as SL wiki
8922 8698
8923 LSL_List res = new LSL_List(); 8699 if (remaining != null && remaining.Length > 0)
8924// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8925 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8926
8927 int idx = 0;
8928 while (idx < rules.Length)
8929 {
8930 int code = (int)rules.GetLSLIntegerItem(idx++);
8931 int remain = rules.Length - idx;
8932
8933 switch (code)
8934 { 8700 {
8935 case (int)ScriptBaseClass.PRIM_MATERIAL: 8701 linknumber = remaining.GetLSLIntegerItem(0);
8936 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); 8702 rules = remaining.GetSublist(1, -1);
8937 break;
8938
8939 case (int)ScriptBaseClass.PRIM_PHYSICS:
8940 res.Add(new LSL_Integer(0));
8941 break;
8942
8943 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8944 res.Add(new LSL_Integer(0));
8945 break;
8946
8947 case (int)ScriptBaseClass.PRIM_PHANTOM:
8948 res.Add(new LSL_Integer(0));
8949 break;
8950
8951 case (int)ScriptBaseClass.PRIM_POSITION:
8952
8953 Vector3 pos = avatar.OffsetPosition;
8954
8955 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8956 pos -= sitOffset;
8957
8958 if( sitPart != null)
8959 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8960
8961 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8962 break;
8963
8964 case (int)ScriptBaseClass.PRIM_SIZE:
8965 // as in llGetAgentSize above
8966 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8967 break;
8968
8969 case (int)ScriptBaseClass.PRIM_ROTATION:
8970 Quaternion rot = avatar.Rotation;
8971 if (sitPart != null)
8972 {
8973 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8974 }
8975
8976 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8977 break;
8978
8979 case (int)ScriptBaseClass.PRIM_TYPE:
8980 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8981 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8982 res.Add(new LSL_Vector(0f,1.0f,0f));
8983 res.Add(new LSL_Float(0.0f));
8984 res.Add(new LSL_Vector(0, 0, 0));
8985 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8986 res.Add(new LSL_Vector(0, 0, 0));
8987 break;
8988
8989 case (int)ScriptBaseClass.PRIM_TEXTURE:
8990 if (remain < 1)
8991 return res;
8992
8993 int face = (int)rules.GetLSLIntegerItem(idx++);
8994 if (face == ScriptBaseClass.ALL_SIDES)
8995 {
8996 for (face = 0; face < 21; face++)
8997 {
8998 res.Add(new LSL_String(""));
8999 res.Add(new LSL_Vector(0,0,0));
9000 res.Add(new LSL_Vector(0,0,0));
9001 res.Add(new LSL_Float(0.0));
9002 }
9003 }
9004 else
9005 {
9006 if (face >= 0 && face < 21)
9007 {
9008 res.Add(new LSL_String(""));
9009 res.Add(new LSL_Vector(0,0,0));
9010 res.Add(new LSL_Vector(0,0,0));
9011 res.Add(new LSL_Float(0.0));
9012 }
9013 }
9014 break;
9015
9016 case (int)ScriptBaseClass.PRIM_COLOR:
9017 if (remain < 1)
9018 return res;
9019
9020 face = (int)rules.GetLSLIntegerItem(idx++);
9021
9022 if (face == ScriptBaseClass.ALL_SIDES)
9023 {
9024 for (face = 0; face < 21; face++)
9025 {
9026 res.Add(new LSL_Vector(0,0,0));
9027 res.Add(new LSL_Float(0));
9028 }
9029 }
9030 else
9031 {
9032 res.Add(new LSL_Vector(0,0,0));
9033 res.Add(new LSL_Float(0));
9034 }
9035 break;
9036
9037 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9038 if (remain < 1)
9039 return res;
9040 face = (int)rules.GetLSLIntegerItem(idx++);
9041
9042 if (face == ScriptBaseClass.ALL_SIDES)
9043 {
9044 for (face = 0; face < 21; face++)
9045 {
9046 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9047 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9048 }
9049 }
9050 else
9051 {
9052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9054 }
9055 break;
9056
9057 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9058 if (remain < 1)
9059 return res;
9060 face = (int)rules.GetLSLIntegerItem(idx++);
9061
9062 if (face == ScriptBaseClass.ALL_SIDES)
9063 {
9064 for (face = 0; face < 21; face++)
9065 {
9066 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9067 }
9068 }
9069 else
9070 {
9071 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9072 }
9073 break;
9074
9075 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9076 res.Add(new LSL_Integer(0));
9077 res.Add(new LSL_Integer(0));// softness
9078 res.Add(new LSL_Float(0.0f)); // gravity
9079 res.Add(new LSL_Float(0.0f)); // friction
9080 res.Add(new LSL_Float(0.0f)); // wind
9081 res.Add(new LSL_Float(0.0f)); // tension
9082 res.Add(new LSL_Vector(0f,0f,0f));
9083 break;
9084
9085 case (int)ScriptBaseClass.PRIM_TEXGEN:
9086 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9087 if (remain < 1)
9088 return res;
9089 face = (int)rules.GetLSLIntegerItem(idx++);
9090
9091 if (face == ScriptBaseClass.ALL_SIDES)
9092 {
9093 for (face = 0; face < 21; face++)
9094 {
9095 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9096 }
9097 }
9098 else
9099 {
9100 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9101 }
9102 break;
9103
9104 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9105 res.Add(new LSL_Integer(0));
9106 res.Add(new LSL_Vector(0f,0f,0f));
9107 res.Add(new LSL_Float(0f)); // intensity
9108 res.Add(new LSL_Float(0f)); // radius
9109 res.Add(new LSL_Float(0f)); // falloff
9110 break;
9111
9112 case (int)ScriptBaseClass.PRIM_GLOW:
9113 if (remain < 1)
9114 return res;
9115 face = (int)rules.GetLSLIntegerItem(idx++);
9116
9117 if (face == ScriptBaseClass.ALL_SIDES)
9118 {
9119 for (face = 0; face < 21; face++)
9120 {
9121 res.Add(new LSL_Float(0f));
9122 }
9123 }
9124 else
9125 {
9126 res.Add(new LSL_Float(0f));
9127 }
9128 break;
9129
9130 case (int)ScriptBaseClass.PRIM_TEXT:
9131 res.Add(new LSL_String(""));
9132 res.Add(new LSL_Vector(0f,0f,0f));
9133 res.Add(new LSL_Float(1.0f));
9134 break;
9135
9136 case (int)ScriptBaseClass.PRIM_NAME:
9137 res.Add(new LSL_String(avatar.Name));
9138 break;
9139
9140 case (int)ScriptBaseClass.PRIM_DESC:
9141 res.Add(new LSL_String(""));
9142 break;
9143
9144 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9145 Quaternion lrot = avatar.Rotation;
9146
9147 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9148 {
9149 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9150 }
9151 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9152 break;
9153
9154 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9155 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9156 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9157 lpos -= lsitOffset;
9158
9159 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9160 {
9161 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9162 }
9163 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9164 break;
9165
9166 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9167 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9168 return res;
9169 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9170 LSL_List new_rules = rules.GetSublist(idx, -1);
9171
9172 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9173 return res;
9174 } 8703 }
9175 } 8704 }
8705
9176 return res; 8706 return res;
9177 } 8707 }
9178 8708
9179 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 8709 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
9180 { 8710 {
9181 LSL_List res = new LSL_List();
9182 int idx=0; 8711 int idx=0;
9183 while (idx < rules.Length) 8712 while (idx < rules.Length)
9184 { 8713 {
@@ -9316,7 +8845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9316 8845
9317 case (int)ScriptBaseClass.PRIM_TEXTURE: 8846 case (int)ScriptBaseClass.PRIM_TEXTURE:
9318 if (remain < 1) 8847 if (remain < 1)
9319 return res; 8848 return null;
9320 8849
9321 int face = (int)rules.GetLSLIntegerItem(idx++); 8850 int face = (int)rules.GetLSLIntegerItem(idx++);
9322 Primitive.TextureEntry tex = part.Shape.Textures; 8851 Primitive.TextureEntry tex = part.Shape.Textures;
@@ -9356,7 +8885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9356 8885
9357 case (int)ScriptBaseClass.PRIM_COLOR: 8886 case (int)ScriptBaseClass.PRIM_COLOR:
9358 if (remain < 1) 8887 if (remain < 1)
9359 return res; 8888 return null;
9360 8889
9361 face=(int)rules.GetLSLIntegerItem(idx++); 8890 face=(int)rules.GetLSLIntegerItem(idx++);
9362 8891
@@ -9385,7 +8914,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9385 8914
9386 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8915 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9387 if (remain < 1) 8916 if (remain < 1)
9388 return res; 8917 return null;
8918
9389 face = (int)rules.GetLSLIntegerItem(idx++); 8919 face = (int)rules.GetLSLIntegerItem(idx++);
9390 8920
9391 tex = part.Shape.Textures; 8921 tex = part.Shape.Textures;
@@ -9441,7 +8971,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 8971
9442 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8972 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9443 if (remain < 1) 8973 if (remain < 1)
9444 return res; 8974 return null;
8975
9445 face = (int)rules.GetLSLIntegerItem(idx++); 8976 face = (int)rules.GetLSLIntegerItem(idx++);
9446 8977
9447 tex = part.Shape.Textures; 8978 tex = part.Shape.Textures;
@@ -9495,7 +9026,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9495 case (int)ScriptBaseClass.PRIM_TEXGEN: 9026 case (int)ScriptBaseClass.PRIM_TEXGEN:
9496 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 9027 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9497 if (remain < 1) 9028 if (remain < 1)
9498 return res; 9029 return null;
9030
9499 face = (int)rules.GetLSLIntegerItem(idx++); 9031 face = (int)rules.GetLSLIntegerItem(idx++);
9500 9032
9501 tex = part.Shape.Textures; 9033 tex = part.Shape.Textures;
@@ -9543,7 +9075,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9543 9075
9544 case (int)ScriptBaseClass.PRIM_GLOW: 9076 case (int)ScriptBaseClass.PRIM_GLOW:
9545 if (remain < 1) 9077 if (remain < 1)
9546 return res; 9078 return null;
9079
9547 face = (int)rules.GetLSLIntegerItem(idx++); 9080 face = (int)rules.GetLSLIntegerItem(idx++);
9548 9081
9549 tex = part.Shape.Textures; 9082 tex = part.Shape.Textures;
@@ -9587,18 +9120,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9587 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9120 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9588 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9121 res.Add(new LSL_Vector(GetPartLocalPos(part)));
9589 break; 9122 break;
9590 9123 case (int)ScriptBaseClass.PRIM_SLICE:
9124 PrimType prim_type = part.GetPrimType();
9125 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
9126 res.Add(new LSL_Vector(
9127 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
9128 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
9129 0
9130 ));
9131 break;
9591 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9132 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9592 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 9133 if(remain < 3)
9593 return res; 9134 return null;
9594 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 9135
9595 LSL_List new_rules = rules.GetSublist(idx, -1); 9136 return rules.GetSublist(idx, -1);
9596 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9597 res += tres;
9598 return res;
9599 } 9137 }
9600 } 9138 }
9601 return res; 9139
9140 return null;
9602 } 9141 }
9603 9142
9604 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 9143 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -10511,11 +10050,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10511 10050
10512 GridRegion info; 10051 GridRegion info;
10513 10052
10514 if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) //Det data for this simulator? 10053 if (World.RegionInfo.RegionName == simulator)
10515 10054 info = new GridRegion(World.RegionInfo);
10516 info = new GridRegion(m_ScriptEngine.World.RegionInfo);
10517 else 10055 else
10518 info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 10056 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
10519 10057
10520 switch (data) 10058 switch (data)
10521 { 10059 {
@@ -10525,9 +10063,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 ScriptSleep(1000); 10063 ScriptSleep(1000);
10526 return UUID.Zero.ToString(); 10064 return UUID.Zero.ToString();
10527 } 10065 }
10528 if (m_ScriptEngine.World.RegionInfo.RegionName != simulator) 10066
10067 bool isHypergridRegion = false;
10068
10069 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "")
10070 {
10071 // Hypergrid is currently placing real destination region co-ords into RegionSecret.
10072 // But other code can also use this field for a genuine RegionSecret! Therefore, if
10073 // anything is present we need to disambiguate.
10074 //
10075 // FIXME: Hypergrid should be storing this data in a different field.
10076 RegionFlags regionFlags
10077 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags(
10078 info.ScopeID, info.RegionID);
10079 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0;
10080 }
10081
10082 if (isHypergridRegion)
10529 { 10083 {
10530 //Hypergrid Region co-ordinates
10531 uint rx = 0, ry = 0; 10084 uint rx = 0, ry = 0;
10532 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); 10085 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry);
10533 10086
@@ -10538,7 +10091,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10538 } 10091 }
10539 else 10092 else
10540 { 10093 {
10541 //Local-cooridnates 10094 // Local grid co-oridnates
10542 reply = new LSL_Vector( 10095 reply = new LSL_Vector(
10543 info.RegionLocX, 10096 info.RegionLocX,
10544 info.RegionLocY, 10097 info.RegionLocY,
@@ -10992,20 +10545,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10992 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) 10545 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10993 { 10546 {
10994 case ParcelMediaCommandEnum.Url: 10547 case ParcelMediaCommandEnum.Url:
10995 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10548 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10996 break; 10549 break;
10997 case ParcelMediaCommandEnum.Desc: 10550 case ParcelMediaCommandEnum.Desc:
10998 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).Description)); 10551 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10999 break; 10552 break;
11000 case ParcelMediaCommandEnum.Texture: 10553 case ParcelMediaCommandEnum.Texture:
11001 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaID.ToString())); 10554 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
11002 break; 10555 break;
11003 case ParcelMediaCommandEnum.Type: 10556 case ParcelMediaCommandEnum.Type:
11004 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 10557 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
11005 break; 10558 break;
11006 case ParcelMediaCommandEnum.Size: 10559 case ParcelMediaCommandEnum.Size:
11007 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth)); 10560 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth));
11008 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight)); 10561 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
11009 break; 10562 break;
11010 default: 10563 default:
11011 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10564 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
@@ -11175,9 +10728,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10728 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
11176 if (avatar != null) 10729 if (avatar != null)
11177 { 10730 {
11178 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, 10731 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
11179 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10732 simname, pos, lookAt);
11180 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
11181 } 10733 }
11182 10734
11183 ScriptSleep(1000); 10735 ScriptSleep(1000);
@@ -11362,31 +10914,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11362 public LSL_Float llListStatistics(int operation, LSL_List src) 10914 public LSL_Float llListStatistics(int operation, LSL_List src)
11363 { 10915 {
11364 m_host.AddScriptLPS(1); 10916 m_host.AddScriptLPS(1);
11365 LSL_List nums = LSL_List.ToDoubleList(src);
11366 switch (operation) 10917 switch (operation)
11367 { 10918 {
11368 case ScriptBaseClass.LIST_STAT_RANGE: 10919 case ScriptBaseClass.LIST_STAT_RANGE:
11369 return nums.Range(); 10920 return src.Range();
11370 case ScriptBaseClass.LIST_STAT_MIN: 10921 case ScriptBaseClass.LIST_STAT_MIN:
11371 return nums.Min(); 10922 return src.Min();
11372 case ScriptBaseClass.LIST_STAT_MAX: 10923 case ScriptBaseClass.LIST_STAT_MAX:
11373 return nums.Max(); 10924 return src.Max();
11374 case ScriptBaseClass.LIST_STAT_MEAN: 10925 case ScriptBaseClass.LIST_STAT_MEAN:
11375 return nums.Mean(); 10926 return src.Mean();
11376 case ScriptBaseClass.LIST_STAT_MEDIAN: 10927 case ScriptBaseClass.LIST_STAT_MEDIAN:
11377 return nums.Median(); 10928 return LSL_List.ToDoubleList(src).Median();
11378 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10929 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
11379 return nums.NumericLength(); 10930 return src.NumericLength();
11380 case ScriptBaseClass.LIST_STAT_STD_DEV: 10931 case ScriptBaseClass.LIST_STAT_STD_DEV:
11381 return nums.StdDev(); 10932 return src.StdDev();
11382 case ScriptBaseClass.LIST_STAT_SUM: 10933 case ScriptBaseClass.LIST_STAT_SUM:
11383 return nums.Sum(); 10934 return src.Sum();
11384 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10935 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
11385 return nums.SumSqrs(); 10936 return src.SumSqrs();
11386 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10937 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
11387 return nums.GeometricMean(); 10938 return src.GeometricMean();
11388 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10939 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
11389 return nums.HarmonicMean(); 10940 return src.HarmonicMean();
11390 default: 10941 default:
11391 return 0.0; 10942 return 0.0;
11392 } 10943 }
@@ -11744,7 +11295,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11744 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 11295 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
11745 { 11296 {
11746 m_host.AddScriptLPS(1); 11297 m_host.AddScriptLPS(1);
11747 LandData land = World.GetLandData((float)pos.x, (float)pos.y); 11298 LandData land = World.GetLandData(pos);
11748 if (land == null) 11299 if (land == null)
11749 { 11300 {
11750 return new LSL_List(0); 11301 return new LSL_List(0);
@@ -11912,13 +11463,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11912 else 11463 else
11913 rot = obj.GetWorldRotation(); 11464 rot = obj.GetWorldRotation();
11914 11465
11915 LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); 11466 LSL_Rotation objrot = new LSL_Rotation(rot);
11916 ret.Add(objrot); 11467 ret.Add(objrot);
11917 } 11468 }
11918 break; 11469 break;
11919 case ScriptBaseClass.OBJECT_VELOCITY: 11470 case ScriptBaseClass.OBJECT_VELOCITY:
11920 Vector3 ovel = obj.Velocity; 11471 ret.Add(new LSL_Vector(obj.Velocity));
11921 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
11922 break; 11472 break;
11923 case ScriptBaseClass.OBJECT_OWNER: 11473 case ScriptBaseClass.OBJECT_OWNER:
11924 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11474 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -12005,12 +11555,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12005 11555
12006 internal void Deprecated(string command) 11556 internal void Deprecated(string command)
12007 { 11557 {
12008 throw new Exception("Command deprecated: " + command); 11558 throw new ScriptException("Command deprecated: " + command);
12009 } 11559 }
12010 11560
12011 internal void LSLError(string msg) 11561 internal void LSLError(string msg)
12012 { 11562 {
12013 throw new Exception("LSL Runtime Error: " + msg); 11563 throw new ScriptException("LSL Runtime Error: " + msg);
12014 } 11564 }
12015 11565
12016 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset); 11566 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset);
@@ -12131,7 +11681,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12131 return tid.ToString(); 11681 return tid.ToString();
12132 } 11682 }
12133 11683
12134 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11684 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
12135 { 11685 {
12136 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11686 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12137 if (obj == null) 11687 if (obj == null)
@@ -12140,28 +11690,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12140 if (obj.OwnerID != m_host.OwnerID) 11690 if (obj.OwnerID != m_host.OwnerID)
12141 return; 11691 return;
12142 11692
12143 LSL_List remaining = SetPrimParams(obj, rules); 11693 uint rulesParsed = 0;
11694 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
12144 11695
12145 while ((object)remaining != null && remaining.Length > 2) 11696 while ((object)remaining != null && remaining.Length > 2)
12146 { 11697 {
12147 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11698 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
12148 LSL_List newrules = remaining.GetSublist(1, -1); 11699 LSL_List newrules = remaining.GetSublist(1, -1);
12149 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11700 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
12150 remaining = SetPrimParams(part, newrules); 11701 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
12151 } 11702 }
12152 } 11703 }
12153 } 11704 }
12154 11705
12155 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11706 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
12156 { 11707 {
12157 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11708 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12158 if (obj == null)
12159 return new LSL_List();
12160 11709
12161 if (obj.OwnerID != m_host.OwnerID) 11710 LSL_List result = new LSL_List();
12162 return new LSL_List();
12163 11711
12164 return GetLinkPrimitiveParams(obj, rules); 11712 if (obj != null && obj.OwnerID != m_host.OwnerID)
11713 {
11714 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11715
11716 while (remaining != null && remaining.Length > 2)
11717 {
11718 int linknumber = remaining.GetLSLIntegerItem(0);
11719 rules = remaining.GetSublist(1, -1);
11720 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11721
11722 foreach (SceneObjectPart part in parts)
11723 remaining = GetPrimParams(part, rules, ref result);
11724 }
11725 }
11726
11727 return result;
12165 } 11728 }
12166 11729
12167 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 11730 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
@@ -12524,8 +12087,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12524 12087
12525 m_host.AddScriptLPS(1); 12088 m_host.AddScriptLPS(1);
12526 12089
12527 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); 12090 Vector3 rayStart = start;
12528 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); 12091 Vector3 rayEnd = end;
12529 Vector3 dir = rayEnd - rayStart; 12092 Vector3 dir = rayEnd - rayStart;
12530 12093
12531 float dist = Vector3.Mag(dir); 12094 float dist = Vector3.Mag(dir);
@@ -13099,6 +12662,455 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13099 } 12662 }
13100 } 12663 }
13101 } 12664 }
12665
12666 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12667 {
12668 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12669
12670 int idx = 0;
12671 int idxStart = 0;
12672
12673 bool positionChanged = false;
12674 Vector3 finalPos = Vector3.Zero;
12675
12676 try
12677 {
12678 while (idx < rules.Length)
12679 {
12680 ++rulesParsed;
12681 int code = rules.GetLSLIntegerItem(idx++);
12682
12683 int remain = rules.Length - idx;
12684 idxStart = idx;
12685
12686 switch (code)
12687 {
12688 case (int)ScriptBaseClass.PRIM_POSITION:
12689 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12690 {
12691 if (remain < 1)
12692 return null;
12693
12694 LSL_Vector v;
12695 v = rules.GetVector3Item(idx++);
12696
12697 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12698 if (part == null)
12699 break;
12700
12701 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12702 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12703 if (part.LinkNum > 1)
12704 {
12705 localRot = GetPartLocalRot(part);
12706 localPos = GetPartLocalPos(part);
12707 }
12708
12709 v -= localPos;
12710 v /= localRot;
12711
12712 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12713
12714 v = v + 2 * sitOffset;
12715
12716 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12717 av.SendAvatarDataToAllAgents();
12718
12719 }
12720 break;
12721
12722 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12723 case (int)ScriptBaseClass.PRIM_ROTATION:
12724 {
12725 if (remain < 1)
12726 return null;
12727
12728 LSL_Rotation r;
12729 r = rules.GetQuaternionItem(idx++);
12730
12731 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12732 if (part == null)
12733 break;
12734
12735 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12736 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12737
12738 if (part.LinkNum > 1)
12739 localRot = GetPartLocalRot(part);
12740
12741 r = r * llGetRootRotation() / localRot;
12742 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12743 av.SendAvatarDataToAllAgents();
12744 }
12745 break;
12746
12747 // parse rest doing nothing but number of parameters error check
12748 case (int)ScriptBaseClass.PRIM_SIZE:
12749 case (int)ScriptBaseClass.PRIM_MATERIAL:
12750 case (int)ScriptBaseClass.PRIM_PHANTOM:
12751 case (int)ScriptBaseClass.PRIM_PHYSICS:
12752 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12753 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12754 case (int)ScriptBaseClass.PRIM_NAME:
12755 case (int)ScriptBaseClass.PRIM_DESC:
12756 if (remain < 1)
12757 return null;
12758 idx++;
12759 break;
12760
12761 case (int)ScriptBaseClass.PRIM_GLOW:
12762 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12763 case (int)ScriptBaseClass.PRIM_TEXGEN:
12764 if (remain < 2)
12765 return null;
12766 idx += 2;
12767 break;
12768
12769 case (int)ScriptBaseClass.PRIM_TYPE:
12770 if (remain < 3)
12771 return null;
12772 code = (int)rules.GetLSLIntegerItem(idx++);
12773 remain = rules.Length - idx;
12774 switch (code)
12775 {
12776 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12777 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12778 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12779 if (remain < 6)
12780 return null;
12781 idx += 6;
12782 break;
12783
12784 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12785 if (remain < 5)
12786 return null;
12787 idx += 5;
12788 break;
12789
12790 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12791 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12792 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12793 if (remain < 11)
12794 return null;
12795 idx += 11;
12796 break;
12797
12798 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12799 if (remain < 2)
12800 return null;
12801 idx += 2;
12802 break;
12803 }
12804 break;
12805
12806 case (int)ScriptBaseClass.PRIM_COLOR:
12807 case (int)ScriptBaseClass.PRIM_TEXT:
12808 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12809 case (int)ScriptBaseClass.PRIM_OMEGA:
12810 if (remain < 3)
12811 return null;
12812 idx += 3;
12813 break;
12814
12815 case (int)ScriptBaseClass.PRIM_TEXTURE:
12816 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12817 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12818 if (remain < 5)
12819 return null;
12820 idx += 5;
12821 break;
12822
12823 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12824 if (remain < 7)
12825 return null;
12826
12827 idx += 7;
12828 break;
12829
12830 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12831 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12832 return null;
12833
12834 return rules.GetSublist(idx, -1);
12835 }
12836 }
12837 }
12838 catch (InvalidCastException e)
12839 {
12840 ShoutError(string.Format(
12841 "{0} error running rule #{1}: arg #{2} ",
12842 originFunc, rulesParsed, idx - idxStart) + e.Message);
12843 }
12844 finally
12845 {
12846 if (positionChanged)
12847 {
12848 av.OffsetPosition = finalPos;
12849// av.SendAvatarDataToAllAgents();
12850 av.SendTerseUpdateToAllClients();
12851 positionChanged = false;
12852 }
12853 }
12854 return null;
12855 }
12856
12857 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12858 {
12859 // avatars case
12860 // replies as SL wiki
12861
12862// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12863 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12864
12865 int idx = 0;
12866 while (idx < rules.Length)
12867 {
12868 int code = (int)rules.GetLSLIntegerItem(idx++);
12869 int remain = rules.Length - idx;
12870
12871 switch (code)
12872 {
12873 case (int)ScriptBaseClass.PRIM_MATERIAL:
12874 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12875 break;
12876
12877 case (int)ScriptBaseClass.PRIM_PHYSICS:
12878 res.Add(new LSL_Integer(0));
12879 break;
12880
12881 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12882 res.Add(new LSL_Integer(0));
12883 break;
12884
12885 case (int)ScriptBaseClass.PRIM_PHANTOM:
12886 res.Add(new LSL_Integer(0));
12887 break;
12888
12889 case (int)ScriptBaseClass.PRIM_POSITION:
12890
12891 Vector3 pos = avatar.OffsetPosition;
12892
12893 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12894 pos -= sitOffset;
12895
12896 if( sitPart != null)
12897 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12898
12899 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12900 break;
12901
12902 case (int)ScriptBaseClass.PRIM_SIZE:
12903 // as in llGetAgentSize above
12904 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_ROTATION:
12908 Quaternion rot = avatar.Rotation;
12909 if (sitPart != null)
12910 {
12911 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12912 }
12913
12914 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12915 break;
12916
12917 case (int)ScriptBaseClass.PRIM_TYPE:
12918 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12919 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12920 res.Add(new LSL_Vector(0f,1.0f,0f));
12921 res.Add(new LSL_Float(0.0f));
12922 res.Add(new LSL_Vector(0, 0, 0));
12923 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12924 res.Add(new LSL_Vector(0, 0, 0));
12925 break;
12926
12927 case (int)ScriptBaseClass.PRIM_TEXTURE:
12928 if (remain < 1)
12929 return null;
12930
12931 int face = (int)rules.GetLSLIntegerItem(idx++);
12932 if (face == ScriptBaseClass.ALL_SIDES)
12933 {
12934 for (face = 0; face < 21; face++)
12935 {
12936 res.Add(new LSL_String(""));
12937 res.Add(new LSL_Vector(0,0,0));
12938 res.Add(new LSL_Vector(0,0,0));
12939 res.Add(new LSL_Float(0.0));
12940 }
12941 }
12942 else
12943 {
12944 if (face >= 0 && face < 21)
12945 {
12946 res.Add(new LSL_String(""));
12947 res.Add(new LSL_Vector(0,0,0));
12948 res.Add(new LSL_Vector(0,0,0));
12949 res.Add(new LSL_Float(0.0));
12950 }
12951 }
12952 break;
12953
12954 case (int)ScriptBaseClass.PRIM_COLOR:
12955 if (remain < 1)
12956 return null;
12957
12958 face = (int)rules.GetLSLIntegerItem(idx++);
12959
12960 if (face == ScriptBaseClass.ALL_SIDES)
12961 {
12962 for (face = 0; face < 21; face++)
12963 {
12964 res.Add(new LSL_Vector(0,0,0));
12965 res.Add(new LSL_Float(0));
12966 }
12967 }
12968 else
12969 {
12970 res.Add(new LSL_Vector(0,0,0));
12971 res.Add(new LSL_Float(0));
12972 }
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12976 if (remain < 1)
12977 return null;
12978 face = (int)rules.GetLSLIntegerItem(idx++);
12979
12980 if (face == ScriptBaseClass.ALL_SIDES)
12981 {
12982 for (face = 0; face < 21; face++)
12983 {
12984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12986 }
12987 }
12988 else
12989 {
12990 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12991 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12992 }
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12996 if (remain < 1)
12997 return null;
12998 face = (int)rules.GetLSLIntegerItem(idx++);
12999
13000 if (face == ScriptBaseClass.ALL_SIDES)
13001 {
13002 for (face = 0; face < 21; face++)
13003 {
13004 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13005 }
13006 }
13007 else
13008 {
13009 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13010 }
13011 break;
13012
13013 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13014 res.Add(new LSL_Integer(0));
13015 res.Add(new LSL_Integer(0));// softness
13016 res.Add(new LSL_Float(0.0f)); // gravity
13017 res.Add(new LSL_Float(0.0f)); // friction
13018 res.Add(new LSL_Float(0.0f)); // wind
13019 res.Add(new LSL_Float(0.0f)); // tension
13020 res.Add(new LSL_Vector(0f,0f,0f));
13021 break;
13022
13023 case (int)ScriptBaseClass.PRIM_TEXGEN:
13024 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13025 if (remain < 1)
13026 return null;
13027 face = (int)rules.GetLSLIntegerItem(idx++);
13028
13029 if (face == ScriptBaseClass.ALL_SIDES)
13030 {
13031 for (face = 0; face < 21; face++)
13032 {
13033 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13034 }
13035 }
13036 else
13037 {
13038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13039 }
13040 break;
13041
13042 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13043 res.Add(new LSL_Integer(0));
13044 res.Add(new LSL_Vector(0f,0f,0f));
13045 res.Add(new LSL_Float(0f)); // intensity
13046 res.Add(new LSL_Float(0f)); // radius
13047 res.Add(new LSL_Float(0f)); // falloff
13048 break;
13049
13050 case (int)ScriptBaseClass.PRIM_GLOW:
13051 if (remain < 1)
13052 return null;
13053 face = (int)rules.GetLSLIntegerItem(idx++);
13054
13055 if (face == ScriptBaseClass.ALL_SIDES)
13056 {
13057 for (face = 0; face < 21; face++)
13058 {
13059 res.Add(new LSL_Float(0f));
13060 }
13061 }
13062 else
13063 {
13064 res.Add(new LSL_Float(0f));
13065 }
13066 break;
13067
13068 case (int)ScriptBaseClass.PRIM_TEXT:
13069 res.Add(new LSL_String(""));
13070 res.Add(new LSL_Vector(0f,0f,0f));
13071 res.Add(new LSL_Float(1.0f));
13072 break;
13073
13074 case (int)ScriptBaseClass.PRIM_NAME:
13075 res.Add(new LSL_String(avatar.Name));
13076 break;
13077
13078 case (int)ScriptBaseClass.PRIM_DESC:
13079 res.Add(new LSL_String(""));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13083 Quaternion lrot = avatar.Rotation;
13084
13085 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13086 {
13087 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13088 }
13089 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13090 break;
13091
13092 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13093 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13094 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13095 lpos -= lsitOffset;
13096
13097 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13098 {
13099 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13100 }
13101 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13102 break;
13103
13104 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13105 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13106 return null;
13107
13108 return rules.GetSublist(idx, -1);
13109 }
13110 }
13111
13112 return null;
13113 }
13102 } 13114 }
13103 13115
13104 public class NotecardCache 13116 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..8f34833 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -95,13 +95,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
95 95
96 internal void MODError(string msg) 96 internal void MODError(string msg)
97 { 97 {
98 throw new Exception("MOD Runtime Error: " + msg); 98 throw new ScriptException("MOD Runtime Error: " + msg);
99 } 99 }
100 100
101 // 101 /// <summary>
102 //Dumps an error message on the debug console. 102 /// Dumps an error message on the debug console.
103 // 103 /// </summary>
104 104 /// <param name='message'></param>
105 internal void MODShoutError(string message) 105 internal void MODShoutError(string message)
106 { 106 {
107 if (message.Length > 1023) 107 if (message.Length > 1023)
@@ -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
@@ -361,29 +359,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
361 result[i] = (string)(LSL_String)plist[i]; 359 result[i] = (string)(LSL_String)plist[i];
362 else if (plist[i] is LSL_Integer) 360 else if (plist[i] is LSL_Integer)
363 result[i] = (int)(LSL_Integer)plist[i]; 361 result[i] = (int)(LSL_Integer)plist[i];
362 // The int check exists because of the many plain old int script constants in ScriptBase which
363 // are not LSL_Integers.
364 else if (plist[i] is int)
365 result[i] = plist[i];
364 else if (plist[i] is LSL_Float) 366 else if (plist[i] is LSL_Float)
365 result[i] = (float)(LSL_Float)plist[i]; 367 result[i] = (float)(LSL_Float)plist[i];
366 else if (plist[i] is LSL_Key) 368 else if (plist[i] is LSL_Key)
367 result[i] = new UUID((LSL_Key)plist[i]); 369 result[i] = new UUID((LSL_Key)plist[i]);
368 else if (plist[i] is LSL_Rotation) 370 else if (plist[i] is LSL_Rotation)
369 { 371 result[i] = (Quaternion)((LSL_Rotation)plist[i]);
370 LSL_Rotation rot = (LSL_Rotation)plist[i];
371 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
372 }
373 else if (plist[i] is LSL_Vector) 372 else if (plist[i] is LSL_Vector)
374 { 373 result[i] = (Vector3)((LSL_Vector)plist[i]);
375 LSL_Vector vect = (LSL_Vector)plist[i];
376 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
377 }
378 else 374 else
379 MODError("unknown LSL list element type"); 375 MODError(String.Format("{0}: unknown LSL list element type", fname));
380 } 376 }
381 377
382 return result; 378 return result;
383 } 379 }
384 } 380 }
385 381
386 MODError(String.Format("parameter type mismatch; expecting {0}",type.Name)); 382 MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname));
387 return null; 383 return null;
388 } 384 }
389 385
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 80111f9..51c8c7e 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
@@ -214,7 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
214 } 218 }
215 else 219 else
216 { 220 {
217 throw new Exception("OSSL Runtime Error: " + msg); 221 throw new ScriptException("OSSL Runtime Error: " + msg);
218 } 222 }
219 } 223 }
220 224
@@ -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);
@@ -1782,18 +1789,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1782 protected string LoadNotecard(string notecardNameOrUuid) 1789 protected string LoadNotecard(string notecardNameOrUuid)
1783 { 1790 {
1784 UUID assetID = CacheNotecard(notecardNameOrUuid); 1791 UUID assetID = CacheNotecard(notecardNameOrUuid);
1785 StringBuilder notecardData = new StringBuilder();
1786 1792
1787 for (int count = 0; count < NotecardCache.GetLines(assetID); count++) 1793 if (assetID != UUID.Zero)
1788 { 1794 {
1789 string line = NotecardCache.GetLine(assetID, count) + "\n"; 1795 StringBuilder notecardData = new StringBuilder();
1790 1796
1791// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line); 1797 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1792 1798 {
1793 notecardData.Append(line); 1799 string line = NotecardCache.GetLine(assetID, count) + "\n";
1800
1801 // m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
1802
1803 notecardData.Append(line);
1804 }
1805
1806 return notecardData.ToString();
1794 } 1807 }
1795 1808
1796 return notecardData.ToString(); 1809 return null;
1797 } 1810 }
1798 1811
1799 /// <summary> 1812 /// <summary>
@@ -2259,11 +2272,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2272 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
2260 m_host.AddScriptLPS(1); 2273 m_host.AddScriptLPS(1);
2261 InitLSL(); 2274 InitLSL();
2275 // One needs to cast m_LSL_Api because we're using functions not
2276 // on the ILSL_Api interface.
2277 LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
2262 LSL_List retVal = new LSL_List(); 2278 LSL_List retVal = new LSL_List();
2263 List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber); 2279 LSL_List remaining = null;
2280 List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
2264 foreach (SceneObjectPart part in parts) 2281 foreach (SceneObjectPart part in parts)
2265 { 2282 {
2266 retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules); 2283 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2284 }
2285
2286 while (remaining != null && remaining.Length > 2)
2287 {
2288 linknumber = remaining.GetLSLIntegerItem(0);
2289 rules = remaining.GetSublist(1, -1);
2290 parts = LSL_Api.GetLinkParts(linknumber);
2291
2292 foreach (SceneObjectPart part in parts)
2293 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2267 } 2294 }
2268 return retVal; 2295 return retVal;
2269 } 2296 }
@@ -2352,17 +2379,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2352 return UUID.Zero.ToString(); 2379 return UUID.Zero.ToString();
2353 } 2380 }
2354 } 2381 }
2382 else
2383 {
2384 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
2385 }
2355 } 2386 }
2356 2387
2357 if (appearance == null)
2358 return new LSL_Key(UUID.Zero.ToString());
2359
2360 UUID ownerID = UUID.Zero; 2388 UUID ownerID = UUID.Zero;
2361 if (owned) 2389 if (owned)
2362 ownerID = m_host.OwnerID; 2390 ownerID = m_host.OwnerID;
2363 UUID x = module.CreateNPC(firstname, 2391 UUID x = module.CreateNPC(firstname,
2364 lastname, 2392 lastname,
2365 new Vector3((float) position.x, (float) position.y, (float) position.z), 2393 position,
2366 ownerID, 2394 ownerID,
2367 senseAsAgent, 2395 senseAsAgent,
2368 World, 2396 World,
@@ -2425,6 +2453,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2425 return; 2453 return;
2426 2454
2427 string appearanceSerialized = LoadNotecard(notecard); 2455 string appearanceSerialized = LoadNotecard(notecard);
2456
2457 if (appearanceSerialized == null)
2458 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
2459
2428 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2460 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2429// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); 2461// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
2430// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized); 2462// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized);
@@ -2485,7 +2517,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2485 return new LSL_Vector(0, 0, 0); 2517 return new LSL_Vector(0, 0, 0);
2486 } 2518 }
2487 2519
2488 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2520 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2489 { 2521 {
2490 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2522 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2491 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
@@ -2500,7 +2532,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2532 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2501 return; 2533 return;
2502 2534
2503 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2504 module.MoveToTarget(npcId, World, pos, false, true, false); 2535 module.MoveToTarget(npcId, World, pos, false, true, false);
2505 } 2536 }
2506 } 2537 }
@@ -2520,11 +2551,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2520 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2551 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2521 return; 2552 return;
2522 2553
2523 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2524 module.MoveToTarget( 2554 module.MoveToTarget(
2525 new UUID(npc.m_string), 2555 new UUID(npc.m_string),
2526 World, 2556 World,
2527 pos, 2557 target,
2528 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, 2558 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2529 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, 2559 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
2530 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); 2560 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
@@ -2576,7 +2606,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2576 ScenePresence sp = World.GetScenePresence(npcId); 2606 ScenePresence sp = World.GetScenePresence(npcId);
2577 2607
2578 if (sp != null) 2608 if (sp != null)
2579 sp.Rotation = LSL_Api.Rot2Quaternion(rotation); 2609 sp.Rotation = rotation;
2580 } 2610 }
2581 } 2611 }
2582 2612
@@ -2936,7 +2966,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2936 avatar.SpeedModifier = (float)SpeedModifier; 2966 avatar.SpeedModifier = (float)SpeedModifier;
2937 } 2967 }
2938 2968
2939 public void osKickAvatar(string FirstName,string SurName,string alert) 2969 public void osKickAvatar(string FirstName, string SurName, string alert)
2940 { 2970 {
2941 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2971 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2942 m_host.AddScriptLPS(1); 2972 m_host.AddScriptLPS(1);
@@ -2950,10 +2980,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2950 sp.ControllingClient.Kick(alert); 2980 sp.ControllingClient.Kick(alert);
2951 2981
2952 // ...and close on our side 2982 // ...and close on our side
2953 sp.Scene.IncomingCloseAgent(sp.UUID); 2983 sp.Scene.IncomingCloseAgent(sp.UUID, false);
2954 } 2984 }
2955 }); 2985 });
2956 } 2986 }
2987
2988 public LSL_Float osGetHealth(string avatar)
2989 {
2990 CheckThreatLevel(ThreatLevel.None, "osGetHealth");
2991 m_host.AddScriptLPS(1);
2992
2993 LSL_Float health = new LSL_Float(-1);
2994 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
2995 if (presence != null) health = presence.Health;
2996 return health;
2997 }
2957 2998
2958 public void osCauseDamage(string avatar, double damage) 2999 public void osCauseDamage(string avatar, double damage)
2959 { 3000 {
@@ -2966,7 +3007,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2966 ScenePresence presence = World.GetScenePresence(avatarId); 3007 ScenePresence presence = World.GetScenePresence(avatarId);
2967 if (presence != null) 3008 if (presence != null)
2968 { 3009 {
2969 LandData land = World.GetLandData((float)pos.X, (float)pos.Y); 3010 LandData land = World.GetLandData(pos);
2970 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage) 3011 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage)
2971 { 3012 {
2972 float health = presence.Health; 3013 float health = presence.Health;
@@ -3013,7 +3054,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 m_host.AddScriptLPS(1); 3054 m_host.AddScriptLPS(1);
3014 InitLSL(); 3055 InitLSL();
3015 3056
3016 return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules); 3057 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3017 } 3058 }
3018 3059
3019 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3060 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
@@ -3022,7 +3063,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 m_host.AddScriptLPS(1); 3063 m_host.AddScriptLPS(1);
3023 InitLSL(); 3064 InitLSL();
3024 3065
3025 m_LSL_Api.SetPrimitiveParamsEx(prim, rules); 3066 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3026 } 3067 }
3027 3068
3028 /// <summary> 3069 /// <summary>
@@ -3254,6 +3295,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3254 } 3295 }
3255 } 3296 }
3256 3297
3298 #region Attachment commands
3299
3257 public void osForceAttachToAvatar(int attachmentPoint) 3300 public void osForceAttachToAvatar(int attachmentPoint)
3258 { 3301 {
3259 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); 3302 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
@@ -3343,6 +3386,175 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3343 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3386 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3344 } 3387 }
3345 3388
3389 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
3390 {
3391 CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
3392
3393 m_host.AddScriptLPS(1);
3394
3395 UUID targetUUID;
3396 ScenePresence target;
3397 LSL_List resp = new LSL_List();
3398
3399 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3400 {
3401 foreach (object point in attachmentPoints.Data)
3402 {
3403 LSL_Integer ipoint = new LSL_Integer(
3404 (point is LSL_Integer || point is int || point is uint) ?
3405 (int)point :
3406 0
3407 );
3408 resp.Add(ipoint);
3409 if (ipoint == 0)
3410 {
3411 // indicates zero attachments
3412 resp.Add(new LSL_Integer(0));
3413 }
3414 else
3415 {
3416 // gets the number of attachments on the attachment point
3417 resp.Add(new LSL_Integer(target.GetAttachments((uint)ipoint).Count));
3418 }
3419 }
3420 }
3421
3422 return resp;
3423 }
3424
3425 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
3426 {
3427 CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
3428 m_host.AddScriptLPS(1);
3429
3430 UUID targetUUID;
3431 ScenePresence target;
3432
3433 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3434 {
3435 List<int> aps = new List<int>();
3436 foreach (object point in attachmentPoints.Data)
3437 {
3438 int ipoint;
3439 if (int.TryParse(point.ToString(), out ipoint))
3440 {
3441 aps.Add(ipoint);
3442 }
3443 }
3444
3445 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3446
3447 bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3448 bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
3449
3450 if (msgAll && invertPoints)
3451 {
3452 return;
3453 }
3454 else if (msgAll || invertPoints)
3455 {
3456 attachments = target.GetAttachments();
3457 }
3458 else
3459 {
3460 foreach (int point in aps)
3461 {
3462 if (point > 0)
3463 {
3464 attachments.AddRange(target.GetAttachments((uint)point));
3465 }
3466 }
3467 }
3468
3469 // if we have no attachments at this point, exit now
3470 if (attachments.Count == 0)
3471 {
3472 return;
3473 }
3474
3475 List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>();
3476
3477 if (invertPoints)
3478 {
3479 foreach (SceneObjectGroup attachment in attachments)
3480 {
3481 if (aps.Contains((int)attachment.AttachmentPoint))
3482 {
3483 ignoreThese.Add(attachment);
3484 }
3485 }
3486 }
3487
3488 foreach (SceneObjectGroup attachment in ignoreThese)
3489 {
3490 attachments.Remove(attachment);
3491 }
3492 ignoreThese.Clear();
3493
3494 // if inverting removed all attachments to check, exit now
3495 if (attachments.Count < 1)
3496 {
3497 return;
3498 }
3499
3500 if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0)
3501 {
3502 foreach (SceneObjectGroup attachment in attachments)
3503 {
3504 if (attachment.RootPart.CreatorID != m_host.CreatorID)
3505 {
3506 ignoreThese.Add(attachment);
3507 }
3508 }
3509
3510 foreach (SceneObjectGroup attachment in ignoreThese)
3511 {
3512 attachments.Remove(attachment);
3513 }
3514 ignoreThese.Clear();
3515
3516 // if filtering by same object creator removed all
3517 // attachments to check, exit now
3518 if (attachments.Count == 0)
3519 {
3520 return;
3521 }
3522 }
3523
3524 if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0)
3525 {
3526 foreach (SceneObjectGroup attachment in attachments)
3527 {
3528 if (attachment.RootPart.CreatorID != m_item.CreatorID)
3529 {
3530 ignoreThese.Add(attachment);
3531 }
3532 }
3533
3534 foreach (SceneObjectGroup attachment in ignoreThese)
3535 {
3536 attachments.Remove(attachment);
3537 }
3538 ignoreThese.Clear();
3539
3540 // if filtering by object creator must match originating
3541 // script creator removed all attachments to check,
3542 // exit now
3543 if (attachments.Count == 0)
3544 {
3545 return;
3546 }
3547 }
3548
3549 foreach (SceneObjectGroup attachment in attachments)
3550 {
3551 MessageObject(attachment.RootPart.UUID, message);
3552 }
3553 }
3554 }
3555
3556 #endregion
3557
3346 /// <summary> 3558 /// <summary>
3347 /// Checks if thing is a UUID. 3559 /// Checks if thing is a UUID.
3348 /// </summary> 3560 /// </summary>
@@ -3392,5 +3604,166 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3392 3604
3393 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3605 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3394 } 3606 }
3607
3608 /// <summary>
3609 /// Sets the response type for an HTTP request/response
3610 /// </summary>
3611 /// <returns></returns>
3612 public void osSetContentType(LSL_Key id, string type)
3613 {
3614 CheckThreatLevel(ThreatLevel.High, "osSetContentType");
3615
3616 if (m_UrlModule != null)
3617 m_UrlModule.HttpContentType(new UUID(id),type);
3618 }
3619
3620 /// Shout an error if the object owner did not grant the script the specified permissions.
3621 /// </summary>
3622 /// <param name="perms"></param>
3623 /// <returns>boolean indicating whether an error was shouted.</returns>
3624 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix)
3625 {
3626 m_host.AddScriptLPS(1);
3627 bool fail = false;
3628 if (m_item.PermsGranter != m_host.OwnerID)
3629 {
3630 fail = true;
3631 OSSLShoutError(string.Format("{0}. Permissions not granted to owner.", errorPrefix));
3632 }
3633 else if ((m_item.PermsMask & perms) == 0)
3634 {
3635 fail = true;
3636 OSSLShoutError(string.Format("{0}. Permissions not granted.", errorPrefix));
3637 }
3638
3639 return fail;
3640 }
3641
3642 protected void DropAttachment(bool checkPerms)
3643 {
3644 if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
3645 {
3646 return;
3647 }
3648
3649 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3650 ScenePresence sp = attachmentsModule == null ? null : m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.OwnerID);
3651
3652 if (attachmentsModule != null && sp != null)
3653 {
3654 attachmentsModule.DetachSingleAttachmentToGround(sp, m_host.ParentGroup.LocalId);
3655 }
3656 }
3657
3658 protected void DropAttachmentAt(bool checkPerms, LSL_Vector pos, LSL_Rotation rot)
3659 {
3660 if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
3661 {
3662 return;
3663 }
3664
3665 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3666 ScenePresence sp = attachmentsModule == null ? null : m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.OwnerID);
3667
3668 if (attachmentsModule != null && sp != null)
3669 {
3670 attachmentsModule.DetachSingleAttachmentToGround(sp, m_host.ParentGroup.LocalId, pos, rot);
3671 }
3672 }
3673
3674 public void osDropAttachment()
3675 {
3676 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment");
3677 m_host.AddScriptLPS(1);
3678
3679 DropAttachment(true);
3680 }
3681
3682 public void osForceDropAttachment()
3683 {
3684 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment");
3685 m_host.AddScriptLPS(1);
3686
3687 DropAttachment(false);
3688 }
3689
3690 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3691 {
3692 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt");
3693 m_host.AddScriptLPS(1);
3694
3695 DropAttachmentAt(true, pos, rot);
3696 }
3697
3698 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3699 {
3700 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt");
3701 m_host.AddScriptLPS(1);
3702
3703 DropAttachmentAt(false, pos, rot);
3704 }
3705
3706 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
3707 {
3708 CheckThreatLevel(ThreatLevel.Low, "osListenRegex");
3709 m_host.AddScriptLPS(1);
3710 UUID keyID;
3711 UUID.TryParse(ID, out keyID);
3712
3713 // if we want the name to be used as a regular expression, ensure it is valid first.
3714 if ((regexBitfield & ScriptBaseClass.OS_LISTEN_REGEX_NAME) == ScriptBaseClass.OS_LISTEN_REGEX_NAME)
3715 {
3716 try
3717 {
3718 Regex.IsMatch("", name);
3719 }
3720 catch (Exception)
3721 {
3722 OSSLShoutError("Name regex is invalid.");
3723 return -1;
3724 }
3725 }
3726
3727 // if we want the msg to be used as a regular expression, ensure it is valid first.
3728 if ((regexBitfield & ScriptBaseClass.OS_LISTEN_REGEX_MESSAGE) == ScriptBaseClass.OS_LISTEN_REGEX_MESSAGE)
3729 {
3730 try
3731 {
3732 Regex.IsMatch("", msg);
3733 }
3734 catch (Exception)
3735 {
3736 OSSLShoutError("Message regex is invalid.");
3737 return -1;
3738 }
3739 }
3740
3741 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
3742 return (wComm == null) ? -1 : wComm.Listen(
3743 m_host.LocalId,
3744 m_item.ItemID,
3745 m_host.UUID,
3746 channelID,
3747 name,
3748 keyID,
3749 msg,
3750 regexBitfield
3751 );
3752 }
3753
3754 public LSL_Integer osRegexIsMatch(string input, string pattern)
3755 {
3756 CheckThreatLevel(ThreatLevel.Low, "osRegexIsMatch");
3757 m_host.AddScriptLPS(1);
3758 try
3759 {
3760 return Regex.IsMatch(input, pattern) ? 1 : 0;
3761 }
3762 catch (Exception)
3763 {
3764 OSSLShoutError("Possible invalid regular expression detected.");
3765 return 0;
3766 }
3767 }
3395 } 3768 }
3396} 3769}
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..c447d1f 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,59 @@ 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);
421
422 /// <summary>
423 /// Identical to llListen except for a bitfield which indicates which
424 /// string parameters should be parsed as regex patterns.
425 /// </summary>
426 /// <param name="channelID"></param>
427 /// <param name="name"></param>
428 /// <param name="ID"></param>
429 /// <param name="msg"></param>
430 /// <param name="regexBitfield">
431 /// OS_LISTEN_REGEX_NAME
432 /// OS_LISTEN_REGEX_MESSAGE
433 /// </param>
434 /// <returns></returns>
435 LSL_Integer osListenRegex(int channelID, string name, string ID,
436 string msg, int regexBitfield);
437
438 /// <summary>
439 /// Wraps to bool Regex.IsMatch(string input, string pattern)
440 /// </summary>
441 /// <param name="input">string to test for match</param>
442 /// <param name="regex">string to use as pattern</param>
443 /// <returns>boolean</returns>
444 LSL_Integer osRegexIsMatch(string input, string pattern);
308 } 445 }
309} 446}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index f989cc6..0dd5a57 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
@@ -560,6 +613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
560 public const int CLICK_ACTION_OPEN = 4; 613 public const int CLICK_ACTION_OPEN = 4;
561 public const int CLICK_ACTION_PLAY = 5; 614 public const int CLICK_ACTION_PLAY = 5;
562 public const int CLICK_ACTION_OPEN_MEDIA = 6; 615 public const int CLICK_ACTION_OPEN_MEDIA = 6;
616 public const int CLICK_ACTION_ZOOM = 7;
563 617
564 // constants for the llDetectedTouch* functions 618 // constants for the llDetectedTouch* functions
565 public const int TOUCH_INVALID_FACE = -1; 619 public const int TOUCH_INVALID_FACE = -1;
@@ -687,5 +741,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
687 public const int KFM_CMD_PLAY = 0; 741 public const int KFM_CMD_PLAY = 0;
688 public const int KFM_CMD_STOP = 1; 742 public const int KFM_CMD_STOP = 1;
689 public const int KFM_CMD_PAUSE = 2; 743 public const int KFM_CMD_PAUSE = 2;
744
745 /// <summary>
746 /// process name parameter as regex
747 /// </summary>
748 public const int OS_LISTEN_REGEX_NAME = 0x1;
749
750 /// <summary>
751 /// process message parameter as regex
752 /// </summary>
753 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
690 } 754 }
691} 755}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 94405d2..afa9ae0 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,40 @@ 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 }
995
996 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
997 {
998 return m_OSSL_Functions.osListenRegex(channelID, name, ID, msg, regexBitfield);
999 }
1000
1001 public LSL_Integer osRegexIsMatch(string input, string pattern)
1002 {
1003 return m_OSSL_Functions.osRegexIsMatch(input, pattern);
1004 }
953 } 1005 }
954} 1006}
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/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs b/OpenSim/Region/ScriptEngine/Shared/ScriptException.cs
index fcb544f..ae67fc5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/ScriptException.cs
@@ -26,32 +26,15 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
30 29
31using OpenSim.Framework; 30namespace OpenSim.Region.ScriptEngine.Shared
32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Services.Interfaces;
34using OpenMetaverse;
35
36namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
37{ 31{
38 public class HGUuidGatherer : UuidGatherer 32 public class ScriptException : Exception
39 { 33 {
40 protected string m_assetServerURL; 34 public ScriptException() : base() {}
41 protected HGAssetMapper m_assetMapper;
42 35
43 public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache) 36 public ScriptException(string message) : base(message) {}
44 {
45 m_assetMapper = assMap;
46 m_assetServerURL = assetServerURL;
47 }
48 37
49 protected override AssetBase GetAsset(UUID uuid) 38 public ScriptException(string message, Exception innerException) : base(message, innerException) {}
50 {
51 if (string.Empty == m_assetServerURL)
52 return m_assetCache.Get(uuid.ToString());
53 else
54 return m_assetMapper.FetchAsset(m_assetServerURL, uuid);
55 }
56 } 39 }
57} 40} \ No newline at end of file
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
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index c8718d9..c401794 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -75,76 +75,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
75 m_engine.AddRegion(m_scene); 75 m_engine.AddRegion(m_scene);
76 } 76 }
77 77
78 /// <summary>
79 /// Test creation of an NPC where the appearance data comes from a notecard
80 /// </summary>
81 [Test]
82 public void TestOsNpcCreateUsingAppearanceFromNotecard()
83 {
84 TestHelpers.InMethod();
85// log4net.Config.XmlConfigurator.Configure();
86
87 // Store an avatar with a different height from default in a notecard.
88 UUID userId = TestHelpers.ParseTail(0x1);
89 float newHeight = 1.9f;
90
91 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
92 sp.Appearance.AvatarHeight = newHeight;
93 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
94 SceneObjectPart part = so.RootPart;
95 m_scene.AddSceneObject(so);
96
97 OSSL_Api osslApi = new OSSL_Api();
98 osslApi.Initialize(m_engine, part, null);
99
100 string notecardName = "appearanceNc";
101 osslApi.osOwnerSaveAppearance(notecardName);
102
103 // Try creating a bot using the appearance in the notecard.
104 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
105 Assert.That(npcRaw, Is.Not.Null);
106
107 UUID npcId = new UUID(npcRaw);
108 ScenePresence npc = m_scene.GetScenePresence(npcId);
109 Assert.That(npc, Is.Not.Null);
110 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
111 }
112
113 /// <summary>
114 /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
115 /// </summary>
116 [Test]
117 public void TestOsNpcCreateUsingAppearanceFromAvatar()
118 {
119 TestHelpers.InMethod();
120// TestHelpers.EnableLogging();
121
122 // Store an avatar with a different height from default in a notecard.
123 UUID userId = TestHelpers.ParseTail(0x1);
124 float newHeight = 1.9f;
125
126 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
127 sp.Appearance.AvatarHeight = newHeight;
128 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
129 SceneObjectPart part = so.RootPart;
130 m_scene.AddSceneObject(so);
131
132 OSSL_Api osslApi = new OSSL_Api();
133 osslApi.Initialize(m_engine, part, null);
134
135 string notecardName = "appearanceNc";
136 osslApi.osOwnerSaveAppearance(notecardName);
137
138 // Try creating a bot using the existing avatar's appearance
139 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
140 Assert.That(npcRaw, Is.Not.Null);
141
142 UUID npcId = new UUID(npcRaw);
143 ScenePresence npc = m_scene.GetScenePresence(npcId);
144 Assert.That(npc, Is.Not.Null);
145 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
146 }
147
148 [Test] 78 [Test]
149 public void TestOsOwnerSaveAppearance() 79 public void TestOsOwnerSaveAppearance()
150 { 80 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 25679a6..b49bcc2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -36,6 +36,7 @@ using OpenMetaverse;
36using OpenMetaverse.Assets; 36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.Attachments;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory; 40using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC; 41using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
@@ -71,7 +72,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
71 config.Set("Enabled", "true"); 72 config.Set("Enabled", "true");
72 73
73 m_scene = new SceneHelpers().SetupScene(); 74 m_scene = new SceneHelpers().SetupScene();
74 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule()); 75 SceneHelpers.SetupSceneModules(
76 m_scene, initConfigSource, new AvatarFactoryModule(), new AttachmentsModule(), new NPCModule());
75 77
76 m_engine = new XEngine.XEngine(); 78 m_engine = new XEngine.XEngine();
77 m_engine.Initialise(initConfigSource); 79 m_engine.Initialise(initConfigSource);
@@ -79,13 +81,191 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
79 } 81 }
80 82
81 /// <summary> 83 /// <summary>
84 /// Test creation of an NPC where the appearance data comes from a notecard
85 /// </summary>
86 [Test]
87 public void TestOsNpcCreateUsingAppearanceFromNotecard()
88 {
89 TestHelpers.InMethod();
90
91 // Store an avatar with a different height from default in a notecard.
92 UUID userId = TestHelpers.ParseTail(0x1);
93 float newHeight = 1.9f;
94
95 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
96 sp.Appearance.AvatarHeight = newHeight;
97 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
98 SceneObjectPart part = so.RootPart;
99 m_scene.AddSceneObject(so);
100
101 OSSL_Api osslApi = new OSSL_Api();
102 osslApi.Initialize(m_engine, part, null);
103
104 string notecardName = "appearanceNc";
105 osslApi.osOwnerSaveAppearance(notecardName);
106
107 // Try creating a bot using the appearance in the notecard.
108 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
109 Assert.That(npcRaw, Is.Not.Null);
110
111 UUID npcId = new UUID(npcRaw);
112 ScenePresence npc = m_scene.GetScenePresence(npcId);
113 Assert.That(npc, Is.Not.Null);
114 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
115 }
116
117 [Test]
118 public void TestOsNpcCreateNotExistingNotecard()
119 {
120 TestHelpers.InMethod();
121
122 UUID userId = TestHelpers.ParseTail(0x1);
123
124 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
125 m_scene.AddSceneObject(so);
126
127 OSSL_Api osslApi = new OSSL_Api();
128 osslApi.Initialize(m_engine, so.RootPart, null);
129
130 string npcRaw;
131 bool gotExpectedException = false;
132 try
133 {
134 npcRaw
135 = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), "not existing notecard name");
136 }
137 catch (ScriptException)
138 {
139 gotExpectedException = true;
140 }
141
142 Assert.That(gotExpectedException, Is.True);
143 }
144
145 /// <summary>
146 /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
147 /// </summary>
148 [Test]
149 public void TestOsNpcCreateUsingAppearanceFromAvatar()
150 {
151 TestHelpers.InMethod();
152// TestHelpers.EnableLogging();
153
154 // Store an avatar with a different height from default in a notecard.
155 UUID userId = TestHelpers.ParseTail(0x1);
156 float newHeight = 1.9f;
157
158 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
159 sp.Appearance.AvatarHeight = newHeight;
160 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
161 SceneObjectPart part = so.RootPart;
162 m_scene.AddSceneObject(so);
163
164 OSSL_Api osslApi = new OSSL_Api();
165 osslApi.Initialize(m_engine, part, null);
166
167 string notecardName = "appearanceNc";
168 osslApi.osOwnerSaveAppearance(notecardName);
169
170 // Try creating a bot using the existing avatar's appearance
171 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
172 Assert.That(npcRaw, Is.Not.Null);
173
174 UUID npcId = new UUID(npcRaw);
175 ScenePresence npc = m_scene.GetScenePresence(npcId);
176 Assert.That(npc, Is.Not.Null);
177 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
178 }
179
180 [Test]
181 public void TestOsNpcLoadAppearance()
182 {
183 TestHelpers.InMethod();
184
185 // Store an avatar with a different height from default in a notecard.
186 UUID userId = TestHelpers.ParseTail(0x1);
187 float firstHeight = 1.9f;
188 float secondHeight = 2.1f;
189 string firstAppearanceNcName = "appearanceNc1";
190 string secondAppearanceNcName = "appearanceNc2";
191
192 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
193 sp.Appearance.AvatarHeight = firstHeight;
194 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
195 SceneObjectPart part = so.RootPart;
196 m_scene.AddSceneObject(so);
197
198 OSSL_Api osslApi = new OSSL_Api();
199 osslApi.Initialize(m_engine, part, null);
200
201 osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
202
203 string npcRaw
204 = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), firstAppearanceNcName);
205
206 // Create a second appearance notecard with a different height
207 sp.Appearance.AvatarHeight = secondHeight;
208 osslApi.osOwnerSaveAppearance(secondAppearanceNcName);
209
210 osslApi.osNpcLoadAppearance(npcRaw, secondAppearanceNcName);
211
212 UUID npcId = new UUID(npcRaw);
213 ScenePresence npc = m_scene.GetScenePresence(npcId);
214 Assert.That(npc, Is.Not.Null);
215 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(secondHeight));
216 }
217
218 [Test]
219 public void TestOsNpcLoadAppearanceNotExistingNotecard()
220 {
221 TestHelpers.InMethod();
222
223 // Store an avatar with a different height from default in a notecard.
224 UUID userId = TestHelpers.ParseTail(0x1);
225 float firstHeight = 1.9f;
226 float secondHeight = 2.1f;
227 string firstAppearanceNcName = "appearanceNc1";
228 string secondAppearanceNcName = "appearanceNc2";
229
230 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
231 sp.Appearance.AvatarHeight = firstHeight;
232 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
233 SceneObjectPart part = so.RootPart;
234 m_scene.AddSceneObject(so);
235
236 OSSL_Api osslApi = new OSSL_Api();
237 osslApi.Initialize(m_engine, part, null);
238
239 osslApi.osOwnerSaveAppearance(firstAppearanceNcName);
240
241 string npcRaw
242 = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), firstAppearanceNcName);
243
244 bool gotExpectedException = false;
245 try
246 {
247 osslApi.osNpcLoadAppearance(npcRaw, secondAppearanceNcName);
248 }
249 catch (ScriptException)
250 {
251 gotExpectedException = true;
252 }
253
254 Assert.That(gotExpectedException, Is.True);
255
256 UUID npcId = new UUID(npcRaw);
257 ScenePresence npc = m_scene.GetScenePresence(npcId);
258 Assert.That(npc, Is.Not.Null);
259 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(firstHeight));
260 }
261
262 /// <summary>
82 /// Test removal of an owned NPC. 263 /// Test removal of an owned NPC.
83 /// </summary> 264 /// </summary>
84 [Test] 265 [Test]
85 public void TestOsNpcRemoveOwned() 266 public void TestOsNpcRemoveOwned()
86 { 267 {
87 TestHelpers.InMethod(); 268 TestHelpers.InMethod();
88// log4net.Config.XmlConfigurator.Configure();
89 269
90 // Store an avatar with a different height from default in a notecard. 270 // Store an avatar with a different height from default in a notecard.
91 UUID userId = TestHelpers.ParseTail(0x1); 271 UUID userId = TestHelpers.ParseTail(0x1);
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 5c4174e..9405075 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -96,9 +96,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
96 if (part == null) 96 if (part == null)
97 return; 97 return;
98 98
99 if ((part.ScriptEvents & scriptEvents.money) == 0)
100 part = part.ParentGroup.RootPart;
101
99 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); 102 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount);
100 103
101 part = part.ParentGroup.RootPart; 104// part = part.ParentGroup.RootPart;
102 money(part.LocalId, agentID, amount); 105 money(part.LocalId, agentID, amount);
103 } 106 }
104 107
@@ -152,9 +155,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
152 det[0] = new DetectParams(); 155 det[0] = new DetectParams();
153 det[0].Key = remoteClient.AgentId; 156 det[0].Key = remoteClient.AgentId;
154 det[0].Populate(myScriptEngine.World); 157 det[0].Populate(myScriptEngine.World);
155 det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, 158 det[0].OffsetPos = offsetPos;
156 offsetPos.Y,
157 offsetPos.Z);
158 159
159 if (originalID == 0) 160 if (originalID == 0)
160 { 161 {
@@ -298,9 +299,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
298 foreach (DetectedObject detobj in col.Colliders) 299 foreach (DetectedObject detobj in col.Colliders)
299 { 300 {
300 DetectParams d = new DetectParams(); 301 DetectParams d = new DetectParams();
301 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 302 d.Position = detobj.posVector;
302 detobj.posVector.Y,
303 detobj.posVector.Z);
304 d.Populate(myScriptEngine.World); 303 d.Populate(myScriptEngine.World);
305 det.Add(d); 304 det.Add(d);
306 myScriptEngine.PostObjectEvent(localID, new EventParams( 305 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -318,9 +317,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
318 foreach (DetectedObject detobj in col.Colliders) 317 foreach (DetectedObject detobj in col.Colliders)
319 { 318 {
320 DetectParams d = new DetectParams(); 319 DetectParams d = new DetectParams();
321 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 320 d.Position = detobj.posVector;
322 detobj.posVector.Y,
323 detobj.posVector.Z);
324 d.Populate(myScriptEngine.World); 321 d.Populate(myScriptEngine.World);
325 det.Add(d); 322 det.Add(d);
326 myScriptEngine.PostObjectEvent(localID, new EventParams( 323 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -337,9 +334,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
337 foreach (DetectedObject detobj in col.Colliders) 334 foreach (DetectedObject detobj in col.Colliders)
338 { 335 {
339 DetectParams d = new DetectParams(); 336 DetectParams d = new DetectParams();
340 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 337 d.Position = detobj.posVector;
341 detobj.posVector.Y,
342 detobj.posVector.Z);
343 d.Populate(myScriptEngine.World); 338 d.Populate(myScriptEngine.World);
344 det.Add(d); 339 det.Add(d);
345 myScriptEngine.PostObjectEvent(localID, new EventParams( 340 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -381,8 +376,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
381 myScriptEngine.PostObjectEvent(localID, new EventParams( 376 myScriptEngine.PostObjectEvent(localID, new EventParams(
382 "at_target", new object[] { 377 "at_target", new object[] {
383 new LSL_Types.LSLInteger(handle), 378 new LSL_Types.LSLInteger(handle),
384 new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), 379 new LSL_Types.Vector3(targetpos),
385 new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, 380 new LSL_Types.Vector3(atpos) },
386 new DetectParams[0])); 381 new DetectParams[0]));
387 } 382 }
388 383
@@ -399,8 +394,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
399 myScriptEngine.PostObjectEvent(localID, new EventParams( 394 myScriptEngine.PostObjectEvent(localID, new EventParams(
400 "at_rot_target", new object[] { 395 "at_rot_target", new object[] {
401 new LSL_Types.LSLInteger(handle), 396 new LSL_Types.LSLInteger(handle),
402 new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), 397 new LSL_Types.Quaternion(targetrot),
403 new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, 398 new LSL_Types.Quaternion(atrot) },
404 new DetectParams[0])); 399 new DetectParams[0]));
405 } 400 }
406 401
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index f6cb7df..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -656,7 +656,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
656 if (m_Assemblies.ContainsKey(instance.AssetID)) 656 if (m_Assemblies.ContainsKey(instance.AssetID))
657 { 657 {
658 string assembly = m_Assemblies[instance.AssetID]; 658 string assembly = m_Assemblies[instance.AssetID];
659 instance.SaveState(assembly); 659
660 try
661 {
662 instance.SaveState(assembly);
663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
660 } 672 }
661 673
662 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
@@ -778,7 +790,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
778 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
779 791
780 792
781 i.SaveState(assembly); 793 try
794 {
795 i.SaveState(assembly);
796 }
797 catch (Exception e)
798 {
799 m_log.Error(
800 string.Format(
801 "[XEngine]: Failed to save state of script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
802 i.PrimName, i.ScriptName, i.ItemID, i.ObjectID, World.Name)
803 , e);
804 }
782 } 805 }
783 806
784 instances.Clear(); 807 instances.Clear();
@@ -971,6 +994,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
971 // This delay exists to stop mono problems where script compilation and startup would stop the sim 994 // This delay exists to stop mono problems where script compilation and startup would stop the sim
972 // working properly for the session. 995 // working properly for the session.
973 System.Threading.Thread.Sleep(m_StartDelay); 996 System.Threading.Thread.Sleep(m_StartDelay);
997
998 m_log.InfoFormat("[XEngine]: Performing initial script startup on {0}", m_Scene.Name);
974 } 999 }
975 1000
976 object[] o; 1001 object[] o;
@@ -986,13 +1011,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
986 if (m_InitialStartup) 1011 if (m_InitialStartup)
987 if (scriptsStarted % 50 == 0) 1012 if (scriptsStarted % 50 == 0)
988 m_log.InfoFormat( 1013 m_log.InfoFormat(
989 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1014 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name);
990 } 1015 }
991 } 1016 }
992 1017
993 if (m_InitialStartup) 1018 if (m_InitialStartup)
994 m_log.InfoFormat( 1019 m_log.InfoFormat(
995 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1020 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.Name);
996 1021
997 // NOTE: Despite having a lockless queue, this lock is required 1022 // NOTE: Despite having a lockless queue, this lock is required
998 // to make sure there is never no compile thread while there 1023 // to make sure there is never no compile thread while there
@@ -1053,10 +1078,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1053 return false; 1078 return false;
1054 } 1079 }
1055 1080
1056 UUID assetID = item.AssetID; 1081 m_log.DebugFormat(
1082 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1083 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1084 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1057 1085
1058 //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", 1086 UUID assetID = item.AssetID;
1059 // item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
1060 1087
1061 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); 1088 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
1062 1089
@@ -1235,10 +1262,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1235 item.Name, startParam, postOnRez, 1262 item.Name, startParam, postOnRez,
1236 stateSource, m_MaxScriptQueue); 1263 stateSource, m_MaxScriptQueue);
1237 1264
1238 m_log.DebugFormat( 1265// m_log.DebugFormat(
1239 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1240 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1241 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1242 1269
1243 if (presence != null) 1270 if (presence != null)
1244 { 1271 {
@@ -1554,9 +1581,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1554 else if (p[i] is string) 1581 else if (p[i] is string)
1555 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1582 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1556 else if (p[i] is Vector3) 1583 else if (p[i] is Vector3)
1557 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1584 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1558 else if (p[i] is Quaternion) 1585 else if (p[i] is Quaternion)
1559 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1586 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1560 else if (p[i] is float) 1587 else if (p[i] is float)
1561 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1588 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1562 else 1589 else
@@ -1580,9 +1607,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1580 else if (p[i] is string) 1607 else if (p[i] is string)
1581 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1608 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1582 else if (p[i] is Vector3) 1609 else if (p[i] is Vector3)
1583 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1610 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1584 else if (p[i] is Quaternion) 1611 else if (p[i] is Quaternion)
1585 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1612 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1586 else if (p[i] is float) 1613 else if (p[i] is float)
1587 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1614 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1588 else 1615 else