aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1636
1 files changed, 839 insertions, 797 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..6b63d94 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
@@ -3059,7 +3013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3059 } 3013 }
3060 3014
3061 bool result = money.ObjectGiveMoney( 3015 bool result = money.ObjectGiveMoney(
3062 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3016 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, UUID.Zero);
3063 3017
3064 if (result) 3018 if (result)
3065 return 1; 3019 return 1;
@@ -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,43 @@ 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);
7106 }
7107
7108 public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at)
7109 {
7110 m_host.AddScriptLPS(1);
7111
7112 if (link == ScriptBaseClass.LINK_SET ||
7113 link == ScriptBaseClass.LINK_ALL_CHILDREN ||
7114 link == ScriptBaseClass.LINK_ALL_OTHERS) return;
7115
7116 SceneObjectPart part = null;
7117
7118 switch (link)
7119 {
7120 case ScriptBaseClass.LINK_ROOT:
7121 part = m_host.ParentGroup.RootPart;
7122 break;
7123 case ScriptBaseClass.LINK_THIS:
7124 part = m_host;
7125 break;
7126 default:
7127 part = m_host.ParentGroup.GetLinkNumPart(link);
7128 break;
7129 }
7130
7131 if (null != part)
7132 {
7133 part.SetCameraEyeOffset(eye);
7134 part.SetCameraAtOffset(at);
7135 }
7167 } 7136 }
7168 7137
7169 public LSL_String llDumpList2String(LSL_List src, string seperator) 7138 public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -7185,7 +7154,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7185 public LSL_Integer llScriptDanger(LSL_Vector pos) 7154 public LSL_Integer llScriptDanger(LSL_Vector pos)
7186 { 7155 {
7187 m_host.AddScriptLPS(1); 7156 m_host.AddScriptLPS(1);
7188 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); 7157 bool result = World.ScriptDanger(m_host.LocalId, pos);
7189 if (result) 7158 if (result)
7190 { 7159 {
7191 return 1; 7160 return 1;
@@ -7767,7 +7736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7767 { 7736 {
7768 m_host.AddScriptLPS(1); 7737 m_host.AddScriptLPS(1);
7769 7738
7770 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7739 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7771 7740
7772 ScriptSleep(200); 7741 ScriptSleep(200);
7773 } 7742 }
@@ -7776,10 +7745,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 { 7745 {
7777 m_host.AddScriptLPS(1); 7746 m_host.AddScriptLPS(1);
7778 7747
7779 setLinkPrimParams(linknumber, rules); 7748 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7749
7750 ScriptSleep(200);
7780 } 7751 }
7781 7752
7782 private void setLinkPrimParams(int linknumber, LSL_List rules) 7753 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7783 { 7754 {
7784 List<object> parts = new List<object>(); 7755 List<object> parts = new List<object>();
7785 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7756 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7790,15 +7761,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7790 parts.Add(p); 7761 parts.Add(p);
7791 7762
7792 LSL_List remaining = null; 7763 LSL_List remaining = null;
7764 uint rulesParsed = 0;
7793 7765
7794 if (parts.Count > 0) 7766 if (parts.Count > 0)
7795 { 7767 {
7796 foreach (object part in parts) 7768 foreach (object part in parts)
7797 { 7769 {
7798 if (part is SceneObjectPart) 7770 if (part is SceneObjectPart)
7799 remaining = SetPrimParams((SceneObjectPart)part, rules); 7771 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7800 else 7772 else
7801 remaining = SetPrimParams((ScenePresence)part, rules); 7773 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7802 } 7774 }
7803 7775
7804 while ((object)remaining != null && remaining.Length > 2) 7776 while ((object)remaining != null && remaining.Length > 2)
@@ -7817,9 +7789,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7817 foreach (object part in parts) 7789 foreach (object part in parts)
7818 { 7790 {
7819 if (part is SceneObjectPart) 7791 if (part is SceneObjectPart)
7820 remaining = SetPrimParams((SceneObjectPart)part, rules); 7792 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7821 else 7793 else
7822 remaining = SetPrimParams((ScenePresence)part, rules); 7794 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7823 } 7795 }
7824 } 7796 }
7825 } 7797 }
@@ -7857,6 +7829,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 7829
7858 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7830 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7859 { 7831 {
7832 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7860 llSetLinkPrimitiveParamsFast(linknumber, rules); 7833 llSetLinkPrimitiveParamsFast(linknumber, rules);
7861 ScriptSleep(200); 7834 ScriptSleep(200);
7862 } 7835 }
@@ -7884,195 +7857,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7884 return new Vector3((float)x, (float)y, (float)z); 7857 return new Vector3((float)x, (float)y, (float)z);
7885 } 7858 }
7886 7859
7887 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 7860 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 { 7861 {
8072 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7862 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8073 return null; 7863 return null;
8074 7864
8075 int idx = 0; 7865 int idx = 0;
7866 int idxStart = 0;
8076 7867
8077 SceneObjectGroup parentgrp = part.ParentGroup; 7868 SceneObjectGroup parentgrp = part.ParentGroup;
8078 7869
@@ -8083,9 +7874,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8083 { 7874 {
8084 while (idx < rules.Length) 7875 while (idx < rules.Length)
8085 { 7876 {
7877 ++rulesParsed;
8086 int code = rules.GetLSLIntegerItem(idx++); 7878 int code = rules.GetLSLIntegerItem(idx++);
8087 7879
8088 int remain = rules.Length - idx; 7880 int remain = rules.Length - idx;
7881 idxStart = idx;
8089 7882
8090 int face; 7883 int face;
8091 LSL_Vector v; 7884 LSL_Vector v;
@@ -8115,18 +7908,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 return null; 7908 return null;
8116 7909
8117 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7910 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8118 SceneObjectPart rootPart = parentgrp.RootPart;
8119 // try to let this work as in SL... 7911 // try to let this work as in SL...
8120 if (rootPart == part) 7912 if (part.ParentID == 0)
8121 { 7913 {
8122 // special case: If we are root, rotate complete SOG to new rotation 7914 // special case: If we are root, rotate complete SOG to new rotation
8123 SetRot(part, Rot2Quaternion(q)); 7915 SetRot(part, q);
8124 } 7916 }
8125 else 7917 else
8126 { 7918 {
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. 7919 // 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 7920 SceneObjectPart rootPart = part.ParentGroup.RootPart;
8129 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7921 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
8130 } 7922 }
8131 7923
8132 break; 7924 break;
@@ -8300,8 +8092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8300 LSL_Vector color=rules.GetVector3Item(idx++); 8092 LSL_Vector color=rules.GetVector3Item(idx++);
8301 double alpha=(double)rules.GetLSLFloatItem(idx++); 8093 double alpha=(double)rules.GetLSLFloatItem(idx++);
8302 8094
8303 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 8095 part.SetFaceColorAlpha(face, color, alpha);
8304 SetAlpha(part, alpha, face);
8305 8096
8306 break; 8097 break;
8307 8098
@@ -8449,9 +8240,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8449 string primText = rules.GetLSLStringItem(idx++); 8240 string primText = rules.GetLSLStringItem(idx++);
8450 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 8241 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
8451 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 8242 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
8452 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 8243 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)); 8244 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
8456 8245
8457 break; 8246 break;
@@ -8470,8 +8259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8470 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8259 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8471 if (remain < 1) 8260 if (remain < 1)
8472 return null; 8261 return null;
8473 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8262 SetRot(part, rules.GetQuaternionItem(idx++));
8474 SetRot(part, Rot2Quaternion(lr));
8475 break; 8263 break;
8476 case (int)ScriptBaseClass.PRIM_OMEGA: 8264 case (int)ScriptBaseClass.PRIM_OMEGA:
8477 if (remain < 3) 8265 if (remain < 3)
@@ -8481,7 +8269,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8481 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8269 LSL_Float gain = rules.GetLSLFloatItem(idx++);
8482 TargetOmega(part, axis, (double)spinrate, (double)gain); 8270 TargetOmega(part, axis, (double)spinrate, (double)gain);
8483 break; 8271 break;
8484 8272 case (int)ScriptBaseClass.PRIM_SLICE:
8273 if (remain < 1)
8274 return null;
8275 LSL_Vector slice = rules.GetVector3Item(idx++);
8276 part.UpdateSlice((float)slice.x, (float)slice.y);
8277 break;
8485 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8278 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. 8279 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; 8280 return null;
@@ -8490,6 +8283,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8490 } 8283 }
8491 } 8284 }
8492 } 8285 }
8286 catch (InvalidCastException e)
8287 {
8288 ShoutError(string.Format(
8289 "{0} error running rule #{1}: arg #{2} ",
8290 originFunc, rulesParsed, idx - idxStart) + e.Message);
8291 }
8493 finally 8292 finally
8494 { 8293 {
8495 if (positionChanged) 8294 if (positionChanged)
@@ -8498,12 +8297,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8498 { 8297 {
8499 SceneObjectGroup parent = part.ParentGroup; 8298 SceneObjectGroup parent = part.ParentGroup;
8500 Util.FireAndForget(delegate(object x) { 8299 Util.FireAndForget(delegate(object x) {
8501 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8300 parent.UpdateGroupPosition(currentPosition);
8502 }); 8301 });
8503 } 8302 }
8504 else 8303 else
8505 { 8304 {
8506 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); 8305 part.OffsetPosition = currentPosition;
8507 SceneObjectGroup parent = part.ParentGroup; 8306 SceneObjectGroup parent = part.ParentGroup;
8508 parent.HasGroupChanged = true; 8307 parent.HasGroupChanged = true;
8509 parent.ScheduleGroupForTerseUpdate(); 8308 parent.ScheduleGroupForTerseUpdate();
@@ -8792,7 +8591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8792 // and standing avatar since server 1.36 8591 // and standing avatar since server 1.36
8793 LSL_Vector lower; 8592 LSL_Vector lower;
8794 LSL_Vector upper; 8593 LSL_Vector upper;
8795 if (presence.Animator.Animations.DefaultAnimation.AnimID 8594 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8796 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8595 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8797 { 8596 {
8798 // This is for ground sitting avatars 8597 // This is for ground sitting avatars
@@ -8881,7 +8680,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8881 public LSL_List llGetPrimitiveParams(LSL_List rules) 8680 public LSL_List llGetPrimitiveParams(LSL_List rules)
8882 { 8681 {
8883 m_host.AddScriptLPS(1); 8682 m_host.AddScriptLPS(1);
8884 return GetLinkPrimitiveParams(m_host, rules); 8683
8684 LSL_List result = new LSL_List();
8685
8686 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8687
8688 while (remaining != null && remaining.Length > 2)
8689 {
8690 int linknumber = remaining.GetLSLIntegerItem(0);
8691 rules = remaining.GetSublist(1, -1);
8692 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8693
8694 foreach (SceneObjectPart part in parts)
8695 remaining = GetPrimParams(part, rules, ref result);
8696 }
8697
8698 return result;
8885 } 8699 }
8886 8700
8887 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8701 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -8891,294 +8705,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. 8705 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8892 // keep other options as before 8706 // keep other options as before
8893 8707
8894 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8708 List<SceneObjectPart> parts;
8895 List<ScenePresence> avatars = GetLinkAvatars(linknumber); 8709 List<ScenePresence> avatars;
8896 8710
8897 LSL_List res = new LSL_List(); 8711 LSL_List res = new LSL_List();
8712 LSL_List remaining = null;
8898 8713
8899 if (parts.Count > 0) 8714 while (rules.Length > 0)
8900 { 8715 {
8901 foreach (var part in parts) 8716 parts = GetLinkParts(linknumber);
8717 avatars = GetLinkAvatars(linknumber);
8718
8719 remaining = null;
8720 foreach (SceneObjectPart part in parts)
8902 { 8721 {
8903 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8722 remaining = GetPrimParams(part, rules, ref res);
8904 res += partRes;
8905 } 8723 }
8906 }
8907 if (avatars.Count > 0)
8908 {
8909 foreach (ScenePresence avatar in avatars) 8724 foreach (ScenePresence avatar in avatars)
8910 { 8725 {
8911 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules); 8726 remaining = GetPrimParams(avatar, rules, ref res);
8912 res += avaRes;
8913 } 8727 }
8914 }
8915 return res;
8916 }
8917 8728
8918 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules) 8729 if (remaining != null && remaining.Length > 0)
8919 {
8920 // avatars case
8921 // replies as SL wiki
8922
8923 LSL_List res = new LSL_List();
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 { 8730 {
8935 case (int)ScriptBaseClass.PRIM_MATERIAL: 8731 linknumber = remaining.GetLSLIntegerItem(0);
8936 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); 8732 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 } 8733 }
9175 } 8734 }
8735
9176 return res; 8736 return res;
9177 } 8737 }
9178 8738
9179 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 8739 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
9180 { 8740 {
9181 LSL_List res = new LSL_List();
9182 int idx=0; 8741 int idx=0;
9183 while (idx < rules.Length) 8742 while (idx < rules.Length)
9184 { 8743 {
@@ -9316,7 +8875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9316 8875
9317 case (int)ScriptBaseClass.PRIM_TEXTURE: 8876 case (int)ScriptBaseClass.PRIM_TEXTURE:
9318 if (remain < 1) 8877 if (remain < 1)
9319 return res; 8878 return null;
9320 8879
9321 int face = (int)rules.GetLSLIntegerItem(idx++); 8880 int face = (int)rules.GetLSLIntegerItem(idx++);
9322 Primitive.TextureEntry tex = part.Shape.Textures; 8881 Primitive.TextureEntry tex = part.Shape.Textures;
@@ -9356,7 +8915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9356 8915
9357 case (int)ScriptBaseClass.PRIM_COLOR: 8916 case (int)ScriptBaseClass.PRIM_COLOR:
9358 if (remain < 1) 8917 if (remain < 1)
9359 return res; 8918 return null;
9360 8919
9361 face=(int)rules.GetLSLIntegerItem(idx++); 8920 face=(int)rules.GetLSLIntegerItem(idx++);
9362 8921
@@ -9385,7 +8944,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9385 8944
9386 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8945 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9387 if (remain < 1) 8946 if (remain < 1)
9388 return res; 8947 return null;
8948
9389 face = (int)rules.GetLSLIntegerItem(idx++); 8949 face = (int)rules.GetLSLIntegerItem(idx++);
9390 8950
9391 tex = part.Shape.Textures; 8951 tex = part.Shape.Textures;
@@ -9441,7 +9001,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 9001
9442 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9002 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9443 if (remain < 1) 9003 if (remain < 1)
9444 return res; 9004 return null;
9005
9445 face = (int)rules.GetLSLIntegerItem(idx++); 9006 face = (int)rules.GetLSLIntegerItem(idx++);
9446 9007
9447 tex = part.Shape.Textures; 9008 tex = part.Shape.Textures;
@@ -9495,7 +9056,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9495 case (int)ScriptBaseClass.PRIM_TEXGEN: 9056 case (int)ScriptBaseClass.PRIM_TEXGEN:
9496 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 9057 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9497 if (remain < 1) 9058 if (remain < 1)
9498 return res; 9059 return null;
9060
9499 face = (int)rules.GetLSLIntegerItem(idx++); 9061 face = (int)rules.GetLSLIntegerItem(idx++);
9500 9062
9501 tex = part.Shape.Textures; 9063 tex = part.Shape.Textures;
@@ -9543,7 +9105,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9543 9105
9544 case (int)ScriptBaseClass.PRIM_GLOW: 9106 case (int)ScriptBaseClass.PRIM_GLOW:
9545 if (remain < 1) 9107 if (remain < 1)
9546 return res; 9108 return null;
9109
9547 face = (int)rules.GetLSLIntegerItem(idx++); 9110 face = (int)rules.GetLSLIntegerItem(idx++);
9548 9111
9549 tex = part.Shape.Textures; 9112 tex = part.Shape.Textures;
@@ -9587,18 +9150,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9587 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9150 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9588 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9151 res.Add(new LSL_Vector(GetPartLocalPos(part)));
9589 break; 9152 break;
9590 9153 case (int)ScriptBaseClass.PRIM_SLICE:
9154 PrimType prim_type = part.GetPrimType();
9155 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
9156 res.Add(new LSL_Vector(
9157 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
9158 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
9159 0
9160 ));
9161 break;
9591 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9162 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. 9163 if(remain < 3)
9593 return res; 9164 return null;
9594 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 9165
9595 LSL_List new_rules = rules.GetSublist(idx, -1); 9166 return rules.GetSublist(idx, -1);
9596 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9597 res += tres;
9598 return res;
9599 } 9167 }
9600 } 9168 }
9601 return res; 9169
9170 return null;
9602 } 9171 }
9603 9172
9604 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 9173 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -10511,11 +10080,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10511 10080
10512 GridRegion info; 10081 GridRegion info;
10513 10082
10514 if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) //Det data for this simulator? 10083 if (World.RegionInfo.RegionName == simulator)
10515 10084 info = new GridRegion(World.RegionInfo);
10516 info = new GridRegion(m_ScriptEngine.World.RegionInfo);
10517 else 10085 else
10518 info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 10086 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
10519 10087
10520 switch (data) 10088 switch (data)
10521 { 10089 {
@@ -10525,9 +10093,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 ScriptSleep(1000); 10093 ScriptSleep(1000);
10526 return UUID.Zero.ToString(); 10094 return UUID.Zero.ToString();
10527 } 10095 }
10528 if (m_ScriptEngine.World.RegionInfo.RegionName != simulator) 10096
10097 bool isHypergridRegion = false;
10098
10099 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "")
10100 {
10101 // Hypergrid is currently placing real destination region co-ords into RegionSecret.
10102 // But other code can also use this field for a genuine RegionSecret! Therefore, if
10103 // anything is present we need to disambiguate.
10104 //
10105 // FIXME: Hypergrid should be storing this data in a different field.
10106 RegionFlags regionFlags
10107 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags(
10108 info.ScopeID, info.RegionID);
10109 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0;
10110 }
10111
10112 if (isHypergridRegion)
10529 { 10113 {
10530 //Hypergrid Region co-ordinates
10531 uint rx = 0, ry = 0; 10114 uint rx = 0, ry = 0;
10532 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); 10115 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry);
10533 10116
@@ -10538,7 +10121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10538 } 10121 }
10539 else 10122 else
10540 { 10123 {
10541 //Local-cooridnates 10124 // Local grid co-oridnates
10542 reply = new LSL_Vector( 10125 reply = new LSL_Vector(
10543 info.RegionLocX, 10126 info.RegionLocX,
10544 info.RegionLocY, 10127 info.RegionLocY,
@@ -10992,20 +10575,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10992 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) 10575 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10993 { 10576 {
10994 case ParcelMediaCommandEnum.Url: 10577 case ParcelMediaCommandEnum.Url:
10995 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10578 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10996 break; 10579 break;
10997 case ParcelMediaCommandEnum.Desc: 10580 case ParcelMediaCommandEnum.Desc:
10998 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).Description)); 10581 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10999 break; 10582 break;
11000 case ParcelMediaCommandEnum.Texture: 10583 case ParcelMediaCommandEnum.Texture:
11001 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaID.ToString())); 10584 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
11002 break; 10585 break;
11003 case ParcelMediaCommandEnum.Type: 10586 case ParcelMediaCommandEnum.Type:
11004 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 10587 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
11005 break; 10588 break;
11006 case ParcelMediaCommandEnum.Size: 10589 case ParcelMediaCommandEnum.Size:
11007 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth)); 10590 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)); 10591 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
11009 break; 10592 break;
11010 default: 10593 default:
11011 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10594 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
@@ -11175,9 +10758,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10758 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
11176 if (avatar != null) 10759 if (avatar != null)
11177 { 10760 {
11178 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, 10761 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
11179 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10762 simname, pos, lookAt);
11180 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
11181 } 10763 }
11182 10764
11183 ScriptSleep(1000); 10765 ScriptSleep(1000);
@@ -11362,31 +10944,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11362 public LSL_Float llListStatistics(int operation, LSL_List src) 10944 public LSL_Float llListStatistics(int operation, LSL_List src)
11363 { 10945 {
11364 m_host.AddScriptLPS(1); 10946 m_host.AddScriptLPS(1);
11365 LSL_List nums = LSL_List.ToDoubleList(src);
11366 switch (operation) 10947 switch (operation)
11367 { 10948 {
11368 case ScriptBaseClass.LIST_STAT_RANGE: 10949 case ScriptBaseClass.LIST_STAT_RANGE:
11369 return nums.Range(); 10950 return src.Range();
11370 case ScriptBaseClass.LIST_STAT_MIN: 10951 case ScriptBaseClass.LIST_STAT_MIN:
11371 return nums.Min(); 10952 return src.Min();
11372 case ScriptBaseClass.LIST_STAT_MAX: 10953 case ScriptBaseClass.LIST_STAT_MAX:
11373 return nums.Max(); 10954 return src.Max();
11374 case ScriptBaseClass.LIST_STAT_MEAN: 10955 case ScriptBaseClass.LIST_STAT_MEAN:
11375 return nums.Mean(); 10956 return src.Mean();
11376 case ScriptBaseClass.LIST_STAT_MEDIAN: 10957 case ScriptBaseClass.LIST_STAT_MEDIAN:
11377 return nums.Median(); 10958 return LSL_List.ToDoubleList(src).Median();
11378 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10959 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
11379 return nums.NumericLength(); 10960 return src.NumericLength();
11380 case ScriptBaseClass.LIST_STAT_STD_DEV: 10961 case ScriptBaseClass.LIST_STAT_STD_DEV:
11381 return nums.StdDev(); 10962 return src.StdDev();
11382 case ScriptBaseClass.LIST_STAT_SUM: 10963 case ScriptBaseClass.LIST_STAT_SUM:
11383 return nums.Sum(); 10964 return src.Sum();
11384 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10965 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
11385 return nums.SumSqrs(); 10966 return src.SumSqrs();
11386 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10967 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
11387 return nums.GeometricMean(); 10968 return src.GeometricMean();
11388 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10969 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
11389 return nums.HarmonicMean(); 10970 return src.HarmonicMean();
11390 default: 10971 default:
11391 return 0.0; 10972 return 0.0;
11392 } 10973 }
@@ -11744,7 +11325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11744 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 11325 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
11745 { 11326 {
11746 m_host.AddScriptLPS(1); 11327 m_host.AddScriptLPS(1);
11747 LandData land = World.GetLandData((float)pos.x, (float)pos.y); 11328 LandData land = World.GetLandData(pos);
11748 if (land == null) 11329 if (land == null)
11749 { 11330 {
11750 return new LSL_List(0); 11331 return new LSL_List(0);
@@ -11912,13 +11493,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11912 else 11493 else
11913 rot = obj.GetWorldRotation(); 11494 rot = obj.GetWorldRotation();
11914 11495
11915 LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); 11496 LSL_Rotation objrot = new LSL_Rotation(rot);
11916 ret.Add(objrot); 11497 ret.Add(objrot);
11917 } 11498 }
11918 break; 11499 break;
11919 case ScriptBaseClass.OBJECT_VELOCITY: 11500 case ScriptBaseClass.OBJECT_VELOCITY:
11920 Vector3 ovel = obj.Velocity; 11501 ret.Add(new LSL_Vector(obj.Velocity));
11921 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
11922 break; 11502 break;
11923 case ScriptBaseClass.OBJECT_OWNER: 11503 case ScriptBaseClass.OBJECT_OWNER:
11924 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11504 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -12005,12 +11585,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12005 11585
12006 internal void Deprecated(string command) 11586 internal void Deprecated(string command)
12007 { 11587 {
12008 throw new Exception("Command deprecated: " + command); 11588 throw new ScriptException("Command deprecated: " + command);
12009 } 11589 }
12010 11590
12011 internal void LSLError(string msg) 11591 internal void LSLError(string msg)
12012 { 11592 {
12013 throw new Exception("LSL Runtime Error: " + msg); 11593 throw new ScriptException("LSL Runtime Error: " + msg);
12014 } 11594 }
12015 11595
12016 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset); 11596 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset);
@@ -12131,7 +11711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12131 return tid.ToString(); 11711 return tid.ToString();
12132 } 11712 }
12133 11713
12134 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11714 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
12135 { 11715 {
12136 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11716 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12137 if (obj == null) 11717 if (obj == null)
@@ -12140,28 +11720,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12140 if (obj.OwnerID != m_host.OwnerID) 11720 if (obj.OwnerID != m_host.OwnerID)
12141 return; 11721 return;
12142 11722
12143 LSL_List remaining = SetPrimParams(obj, rules); 11723 uint rulesParsed = 0;
11724 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
12144 11725
12145 while ((object)remaining != null && remaining.Length > 2) 11726 while ((object)remaining != null && remaining.Length > 2)
12146 { 11727 {
12147 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11728 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
12148 LSL_List newrules = remaining.GetSublist(1, -1); 11729 LSL_List newrules = remaining.GetSublist(1, -1);
12149 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11730 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
12150 remaining = SetPrimParams(part, newrules); 11731 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
12151 } 11732 }
12152 } 11733 }
12153 } 11734 }
12154 11735
12155 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11736 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
12156 { 11737 {
12157 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11738 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12158 if (obj == null)
12159 return new LSL_List();
12160 11739
12161 if (obj.OwnerID != m_host.OwnerID) 11740 LSL_List result = new LSL_List();
12162 return new LSL_List(); 11741
11742 if (obj != null && obj.OwnerID != m_host.OwnerID)
11743 {
11744 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11745
11746 while (remaining != null && remaining.Length > 2)
11747 {
11748 int linknumber = remaining.GetLSLIntegerItem(0);
11749 rules = remaining.GetSublist(1, -1);
11750 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11751
11752 foreach (SceneObjectPart part in parts)
11753 remaining = GetPrimParams(part, rules, ref result);
11754 }
11755 }
12163 11756
12164 return GetLinkPrimitiveParams(obj, rules); 11757 return result;
12165 } 11758 }
12166 11759
12167 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 11760 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
@@ -12524,8 +12117,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12524 12117
12525 m_host.AddScriptLPS(1); 12118 m_host.AddScriptLPS(1);
12526 12119
12527 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); 12120 Vector3 rayStart = start;
12528 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); 12121 Vector3 rayEnd = end;
12529 Vector3 dir = rayEnd - rayStart; 12122 Vector3 dir = rayEnd - rayStart;
12530 12123
12531 float dist = Vector3.Mag(dir); 12124 float dist = Vector3.Mag(dir);
@@ -12936,7 +12529,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12936 } 12529 }
12937 12530
12938 bool result = money.ObjectGiveMoney( 12531 bool result = money.ObjectGiveMoney(
12939 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12532 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
12940 12533
12941 if (result) 12534 if (result)
12942 { 12535 {
@@ -13099,6 +12692,455 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13099 } 12692 }
13100 } 12693 }
13101 } 12694 }
12695
12696 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12697 {
12698 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12699
12700 int idx = 0;
12701 int idxStart = 0;
12702
12703 bool positionChanged = false;
12704 Vector3 finalPos = Vector3.Zero;
12705
12706 try
12707 {
12708 while (idx < rules.Length)
12709 {
12710 ++rulesParsed;
12711 int code = rules.GetLSLIntegerItem(idx++);
12712
12713 int remain = rules.Length - idx;
12714 idxStart = idx;
12715
12716 switch (code)
12717 {
12718 case (int)ScriptBaseClass.PRIM_POSITION:
12719 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12720 {
12721 if (remain < 1)
12722 return null;
12723
12724 LSL_Vector v;
12725 v = rules.GetVector3Item(idx++);
12726
12727 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12728 if (part == null)
12729 break;
12730
12731 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12732 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12733 if (part.LinkNum > 1)
12734 {
12735 localRot = GetPartLocalRot(part);
12736 localPos = GetPartLocalPos(part);
12737 }
12738
12739 v -= localPos;
12740 v /= localRot;
12741
12742 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12743
12744 v = v + 2 * sitOffset;
12745
12746 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12747 av.SendAvatarDataToAllAgents();
12748
12749 }
12750 break;
12751
12752 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12753 case (int)ScriptBaseClass.PRIM_ROTATION:
12754 {
12755 if (remain < 1)
12756 return null;
12757
12758 LSL_Rotation r;
12759 r = rules.GetQuaternionItem(idx++);
12760
12761 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12762 if (part == null)
12763 break;
12764
12765 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12766 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12767
12768 if (part.LinkNum > 1)
12769 localRot = GetPartLocalRot(part);
12770
12771 r = r * llGetRootRotation() / localRot;
12772 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12773 av.SendAvatarDataToAllAgents();
12774 }
12775 break;
12776
12777 // parse rest doing nothing but number of parameters error check
12778 case (int)ScriptBaseClass.PRIM_SIZE:
12779 case (int)ScriptBaseClass.PRIM_MATERIAL:
12780 case (int)ScriptBaseClass.PRIM_PHANTOM:
12781 case (int)ScriptBaseClass.PRIM_PHYSICS:
12782 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12783 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12784 case (int)ScriptBaseClass.PRIM_NAME:
12785 case (int)ScriptBaseClass.PRIM_DESC:
12786 if (remain < 1)
12787 return null;
12788 idx++;
12789 break;
12790
12791 case (int)ScriptBaseClass.PRIM_GLOW:
12792 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12793 case (int)ScriptBaseClass.PRIM_TEXGEN:
12794 if (remain < 2)
12795 return null;
12796 idx += 2;
12797 break;
12798
12799 case (int)ScriptBaseClass.PRIM_TYPE:
12800 if (remain < 3)
12801 return null;
12802 code = (int)rules.GetLSLIntegerItem(idx++);
12803 remain = rules.Length - idx;
12804 switch (code)
12805 {
12806 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12807 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12808 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12809 if (remain < 6)
12810 return null;
12811 idx += 6;
12812 break;
12813
12814 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12815 if (remain < 5)
12816 return null;
12817 idx += 5;
12818 break;
12819
12820 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12821 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12822 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12823 if (remain < 11)
12824 return null;
12825 idx += 11;
12826 break;
12827
12828 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12829 if (remain < 2)
12830 return null;
12831 idx += 2;
12832 break;
12833 }
12834 break;
12835
12836 case (int)ScriptBaseClass.PRIM_COLOR:
12837 case (int)ScriptBaseClass.PRIM_TEXT:
12838 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12839 case (int)ScriptBaseClass.PRIM_OMEGA:
12840 if (remain < 3)
12841 return null;
12842 idx += 3;
12843 break;
12844
12845 case (int)ScriptBaseClass.PRIM_TEXTURE:
12846 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12847 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12848 if (remain < 5)
12849 return null;
12850 idx += 5;
12851 break;
12852
12853 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12854 if (remain < 7)
12855 return null;
12856
12857 idx += 7;
12858 break;
12859
12860 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12861 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12862 return null;
12863
12864 return rules.GetSublist(idx, -1);
12865 }
12866 }
12867 }
12868 catch (InvalidCastException e)
12869 {
12870 ShoutError(string.Format(
12871 "{0} error running rule #{1}: arg #{2} ",
12872 originFunc, rulesParsed, idx - idxStart) + e.Message);
12873 }
12874 finally
12875 {
12876 if (positionChanged)
12877 {
12878 av.OffsetPosition = finalPos;
12879// av.SendAvatarDataToAllAgents();
12880 av.SendTerseUpdateToAllClients();
12881 positionChanged = false;
12882 }
12883 }
12884 return null;
12885 }
12886
12887 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12888 {
12889 // avatars case
12890 // replies as SL wiki
12891
12892// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12893 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12894
12895 int idx = 0;
12896 while (idx < rules.Length)
12897 {
12898 int code = (int)rules.GetLSLIntegerItem(idx++);
12899 int remain = rules.Length - idx;
12900
12901 switch (code)
12902 {
12903 case (int)ScriptBaseClass.PRIM_MATERIAL:
12904 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_PHYSICS:
12908 res.Add(new LSL_Integer(0));
12909 break;
12910
12911 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12912 res.Add(new LSL_Integer(0));
12913 break;
12914
12915 case (int)ScriptBaseClass.PRIM_PHANTOM:
12916 res.Add(new LSL_Integer(0));
12917 break;
12918
12919 case (int)ScriptBaseClass.PRIM_POSITION:
12920
12921 Vector3 pos = avatar.OffsetPosition;
12922
12923 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12924 pos -= sitOffset;
12925
12926 if( sitPart != null)
12927 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12928
12929 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12930 break;
12931
12932 case (int)ScriptBaseClass.PRIM_SIZE:
12933 // as in llGetAgentSize above
12934 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12935 break;
12936
12937 case (int)ScriptBaseClass.PRIM_ROTATION:
12938 Quaternion rot = avatar.Rotation;
12939 if (sitPart != null)
12940 {
12941 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12942 }
12943
12944 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_TYPE:
12948 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12949 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12950 res.Add(new LSL_Vector(0f,1.0f,0f));
12951 res.Add(new LSL_Float(0.0f));
12952 res.Add(new LSL_Vector(0, 0, 0));
12953 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12954 res.Add(new LSL_Vector(0, 0, 0));
12955 break;
12956
12957 case (int)ScriptBaseClass.PRIM_TEXTURE:
12958 if (remain < 1)
12959 return null;
12960
12961 int face = (int)rules.GetLSLIntegerItem(idx++);
12962 if (face == ScriptBaseClass.ALL_SIDES)
12963 {
12964 for (face = 0; face < 21; face++)
12965 {
12966 res.Add(new LSL_String(""));
12967 res.Add(new LSL_Vector(0,0,0));
12968 res.Add(new LSL_Vector(0,0,0));
12969 res.Add(new LSL_Float(0.0));
12970 }
12971 }
12972 else
12973 {
12974 if (face >= 0 && face < 21)
12975 {
12976 res.Add(new LSL_String(""));
12977 res.Add(new LSL_Vector(0,0,0));
12978 res.Add(new LSL_Vector(0,0,0));
12979 res.Add(new LSL_Float(0.0));
12980 }
12981 }
12982 break;
12983
12984 case (int)ScriptBaseClass.PRIM_COLOR:
12985 if (remain < 1)
12986 return null;
12987
12988 face = (int)rules.GetLSLIntegerItem(idx++);
12989
12990 if (face == ScriptBaseClass.ALL_SIDES)
12991 {
12992 for (face = 0; face < 21; face++)
12993 {
12994 res.Add(new LSL_Vector(0,0,0));
12995 res.Add(new LSL_Float(0));
12996 }
12997 }
12998 else
12999 {
13000 res.Add(new LSL_Vector(0,0,0));
13001 res.Add(new LSL_Float(0));
13002 }
13003 break;
13004
13005 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13006 if (remain < 1)
13007 return null;
13008 face = (int)rules.GetLSLIntegerItem(idx++);
13009
13010 if (face == ScriptBaseClass.ALL_SIDES)
13011 {
13012 for (face = 0; face < 21; face++)
13013 {
13014 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13015 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13016 }
13017 }
13018 else
13019 {
13020 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13021 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13022 }
13023 break;
13024
13025 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13026 if (remain < 1)
13027 return null;
13028 face = (int)rules.GetLSLIntegerItem(idx++);
13029
13030 if (face == ScriptBaseClass.ALL_SIDES)
13031 {
13032 for (face = 0; face < 21; face++)
13033 {
13034 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13035 }
13036 }
13037 else
13038 {
13039 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13040 }
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13044 res.Add(new LSL_Integer(0));
13045 res.Add(new LSL_Integer(0));// softness
13046 res.Add(new LSL_Float(0.0f)); // gravity
13047 res.Add(new LSL_Float(0.0f)); // friction
13048 res.Add(new LSL_Float(0.0f)); // wind
13049 res.Add(new LSL_Float(0.0f)); // tension
13050 res.Add(new LSL_Vector(0f,0f,0f));
13051 break;
13052
13053 case (int)ScriptBaseClass.PRIM_TEXGEN:
13054 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13055 if (remain < 1)
13056 return null;
13057 face = (int)rules.GetLSLIntegerItem(idx++);
13058
13059 if (face == ScriptBaseClass.ALL_SIDES)
13060 {
13061 for (face = 0; face < 21; face++)
13062 {
13063 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13064 }
13065 }
13066 else
13067 {
13068 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13069 }
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13073 res.Add(new LSL_Integer(0));
13074 res.Add(new LSL_Vector(0f,0f,0f));
13075 res.Add(new LSL_Float(0f)); // intensity
13076 res.Add(new LSL_Float(0f)); // radius
13077 res.Add(new LSL_Float(0f)); // falloff
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_GLOW:
13081 if (remain < 1)
13082 return null;
13083 face = (int)rules.GetLSLIntegerItem(idx++);
13084
13085 if (face == ScriptBaseClass.ALL_SIDES)
13086 {
13087 for (face = 0; face < 21; face++)
13088 {
13089 res.Add(new LSL_Float(0f));
13090 }
13091 }
13092 else
13093 {
13094 res.Add(new LSL_Float(0f));
13095 }
13096 break;
13097
13098 case (int)ScriptBaseClass.PRIM_TEXT:
13099 res.Add(new LSL_String(""));
13100 res.Add(new LSL_Vector(0f,0f,0f));
13101 res.Add(new LSL_Float(1.0f));
13102 break;
13103
13104 case (int)ScriptBaseClass.PRIM_NAME:
13105 res.Add(new LSL_String(avatar.Name));
13106 break;
13107
13108 case (int)ScriptBaseClass.PRIM_DESC:
13109 res.Add(new LSL_String(""));
13110 break;
13111
13112 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13113 Quaternion lrot = avatar.Rotation;
13114
13115 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13116 {
13117 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13118 }
13119 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13120 break;
13121
13122 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13123 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13124 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13125 lpos -= lsitOffset;
13126
13127 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13128 {
13129 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13130 }
13131 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13132 break;
13133
13134 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13135 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13136 return null;
13137
13138 return rules.GetSublist(idx, -1);
13139 }
13140 }
13141
13142 return null;
13143 }
13102 } 13144 }
13103 13145
13104 public class NotecardCache 13146 public class NotecardCache