aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs689
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs613
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs31
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs240
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs229
14 files changed, 1467 insertions, 451 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ecfac6f..18c0dd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -303,35 +303,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
303 switch (linkType) 303 switch (linkType)
304 { 304 {
305 case ScriptBaseClass.LINK_SET: 305 case ScriptBaseClass.LINK_SET:
306 if (m_host.ParentGroup != null) 306 return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
307 {
308 return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
309 }
310 return ret;
311 307
312 case ScriptBaseClass.LINK_ROOT: 308 case ScriptBaseClass.LINK_ROOT:
313 if (m_host.ParentGroup != null) 309 ret = new List<SceneObjectPart>();
314 { 310 ret.Add(m_host.ParentGroup.RootPart);
315 ret = new List<SceneObjectPart>();
316 ret.Add(m_host.ParentGroup.RootPart);
317 return ret;
318 }
319 return ret; 311 return ret;
320 312
321 case ScriptBaseClass.LINK_ALL_OTHERS: 313 case ScriptBaseClass.LINK_ALL_OTHERS:
322 if (m_host.ParentGroup == null)
323 return new List<SceneObjectPart>();
324
325 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); 314 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
326 315
327 if (ret.Contains(m_host)) 316 if (ret.Contains(m_host))
328 ret.Remove(m_host); 317 ret.Remove(m_host);
318
329 return ret; 319 return ret;
330 320
331 case ScriptBaseClass.LINK_ALL_CHILDREN: 321 case ScriptBaseClass.LINK_ALL_CHILDREN:
332 if (m_host.ParentGroup == null)
333 return new List<SceneObjectPart>();
334
335 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts); 322 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
336 323
337 if (ret.Contains(m_host.ParentGroup.RootPart)) 324 if (ret.Contains(m_host.ParentGroup.RootPart))
@@ -342,15 +329,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 return ret; 329 return ret;
343 330
344 default: 331 default:
345 if (linkType < 0 || m_host.ParentGroup == null) 332 if (linkType < 0)
346 return new List<SceneObjectPart>(); 333 return new List<SceneObjectPart>();
334
347 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); 335 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
348 if (target == null) 336 if (target == null)
349 return new List<SceneObjectPart>(); 337 return new List<SceneObjectPart>();
350 ret = new List<SceneObjectPart>(); 338 ret = new List<SceneObjectPart>();
351 ret.Add(target); 339 ret.Add(target);
352 return ret; 340 return ret;
353
354 } 341 }
355 } 342 }
356 343
@@ -450,7 +437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
450 } 437 }
451 438
452 // convert a LSL_Rotation to a Quaternion 439 // convert a LSL_Rotation to a Quaternion
453 protected Quaternion Rot2Quaternion(LSL_Rotation r) 440 public static Quaternion Rot2Quaternion(LSL_Rotation r)
454 { 441 {
455 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); 442 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
456 q.Normalize(); 443 q.Normalize();
@@ -957,6 +944,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
957 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); 944 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
958 } 945 }
959 946
947 public void llRegionSayTo(string target, int channel, string msg)
948 {
949 string error = String.Empty;
950
951 if (msg.Length > 1023)
952 msg = msg.Substring(0, 1023);
953
954 m_host.AddScriptLPS(1);
955
956 UUID TargetID;
957 UUID.TryParse(target, out TargetID);
958
959 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
960 if (wComm != null)
961 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
962 LSLError(error);
963 }
964
960 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 965 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
961 { 966 {
962 m_host.AddScriptLPS(1); 967 m_host.AddScriptLPS(1);
@@ -1214,7 +1219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1214 public virtual void llDie() 1219 public virtual void llDie()
1215 { 1220 {
1216 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1217 if (!m_host.IsAttachment) throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1218 } 1223 }
1219 1224
1220 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1298,8 +1303,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1298 if (value != 0) 1303 if (value != 0)
1299 { 1304 {
1300 SceneObjectGroup group = m_host.ParentGroup; 1305 SceneObjectGroup group = m_host.ParentGroup;
1301 if (group == null)
1302 return;
1303 bool allow = true; 1306 bool allow = true;
1304 1307
1305 foreach (SceneObjectPart part in group.Parts) 1308 foreach (SceneObjectPart part in group.Parts)
@@ -1313,18 +1316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1313 1316
1314 if (!allow) 1317 if (!allow)
1315 return; 1318 return;
1319
1316 m_host.ScriptSetPhysicsStatus(true); 1320 m_host.ScriptSetPhysicsStatus(true);
1317 } 1321 }
1318 else 1322 else
1323 {
1319 m_host.ScriptSetPhysicsStatus(false); 1324 m_host.ScriptSetPhysicsStatus(false);
1325 }
1320 } 1326 }
1321 1327
1322 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) 1328 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM)
1323 { 1329 {
1324 if (value != 0) 1330 m_host.ParentGroup.ScriptSetPhantomStatus(value != 0);
1325 m_host.ScriptSetPhantomStatus(true);
1326 else
1327 m_host.ScriptSetPhantomStatus(false);
1328 } 1331 }
1329 1332
1330 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) 1333 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS)
@@ -1466,8 +1469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1466 protected void SetScale(SceneObjectPart part, LSL_Vector scale) 1469 protected void SetScale(SceneObjectPart part, LSL_Vector scale)
1467 { 1470 {
1468 // TODO: this needs to trigger a persistance save as well 1471 // TODO: this needs to trigger a persistance save as well
1469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 1472 if (part == null || part.ParentGroup.IsDeleted)
1470 return; 1473 return;
1474
1471 if (scale.x < 0.01) 1475 if (scale.x < 0.01)
1472 scale.x = 0.01; 1476 scale.x = 0.01;
1473 if (scale.y < 0.01) 1477 if (scale.y < 0.01)
@@ -1510,7 +1514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1510 { 1514 {
1511 m_host.AddScriptLPS(1); 1515 m_host.AddScriptLPS(1);
1512 m_host.ClickAction = (byte)action; 1516 m_host.ClickAction = (byte)action;
1513 if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; 1517 m_host.ParentGroup.HasGroupChanged = true;
1514 m_host.ScheduleFullUpdate(); 1518 m_host.ScheduleFullUpdate();
1515 return; 1519 return;
1516 } 1520 }
@@ -1786,9 +1790,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 tex.FaceTextures[i].RGBA = texcolor; 1790 tex.FaceTextures[i].RGBA = texcolor;
1787 } 1791 }
1788 } 1792 }
1789 texcolor = tex.DefaultTexture.RGBA; 1793
1790 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1794 // In some cases, the default texture can be null, eg when every face
1791 tex.DefaultTexture.RGBA = texcolor; 1795 // has a unique texture
1796 if (tex.DefaultTexture != null)
1797 {
1798 texcolor = tex.DefaultTexture.RGBA;
1799 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1800 tex.DefaultTexture.RGBA = texcolor;
1801 }
1802
1792 part.UpdateTexture(tex); 1803 part.UpdateTexture(tex);
1793 return; 1804 return;
1794 } 1805 }
@@ -2149,7 +2160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2149 2160
2150 if (part.ParentGroup.RootPart == part) 2161 if (part.ParentGroup.RootPart == part)
2151 { 2162 {
2152 if ((targetPos.z < ground) && disable_underground_movement && m_host.AttachmentPoint == 0) 2163 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2153 targetPos.z = ground; 2164 targetPos.z = ground;
2154 } 2165 }
2155 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2166 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
@@ -2236,14 +2247,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2236 else 2247 else
2237 { 2248 {
2238 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2249 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2239 SceneObjectGroup group = m_host.ParentGroup; 2250 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2240 if (group != null) // a bit paranoid, maybe 2251 if (rootPart != null) // better safe than sorry
2241 { 2252 {
2242 SceneObjectPart rootPart = group.RootPart; 2253 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2243 if (rootPart != null) // again, better safe than sorry
2244 {
2245 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2246 }
2247 } 2254 }
2248 } 2255 }
2249 2256
@@ -2292,6 +2299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2292 { 2299 {
2293 return llGetRootRotation(); 2300 return llGetRootRotation();
2294 } 2301 }
2302
2295 m_host.AddScriptLPS(1); 2303 m_host.AddScriptLPS(1);
2296 Quaternion q = m_host.GetWorldRotation(); 2304 Quaternion q = m_host.GetWorldRotation();
2297 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2305 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
@@ -2302,9 +2310,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2302 Quaternion q; 2310 Quaternion q;
2303 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim 2311 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
2304 { 2312 {
2305 if (part.ParentGroup.RootPart.AttachmentPoint != 0) 2313 if (part.ParentGroup.AttachmentPoint != 0)
2306 { 2314 {
2307 ScenePresence avatar = World.GetScenePresence(part.AttachedAvatar); 2315 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2308 if (avatar != null) 2316 if (avatar != null)
2309 { 2317 {
2310 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2318 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
@@ -2333,15 +2341,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2333 { 2341 {
2334 m_host.AddScriptLPS(1); 2342 m_host.AddScriptLPS(1);
2335 2343
2336 if (m_host.ParentGroup != null) 2344 if (!m_host.ParentGroup.IsDeleted)
2337 { 2345 {
2338 if (!m_host.ParentGroup.IsDeleted) 2346 if (local != 0)
2339 { 2347 force *= llGetRot();
2340 if (local != 0)
2341 force *= llGetRot();
2342 2348
2343 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2349 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z));
2344 }
2345 } 2350 }
2346 } 2351 }
2347 2352
@@ -2351,15 +2356,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 2356
2352 m_host.AddScriptLPS(1); 2357 m_host.AddScriptLPS(1);
2353 2358
2354 if (m_host.ParentGroup != null) 2359 if (!m_host.ParentGroup.IsDeleted)
2355 { 2360 {
2356 if (!m_host.ParentGroup.IsDeleted) 2361 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce();
2357 { 2362 force.x = tmpForce.X;
2358 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2363 force.y = tmpForce.Y;
2359 force.x = tmpForce.X; 2364 force.z = tmpForce.Z;
2360 force.y = tmpForce.Y;
2361 force.z = tmpForce.Z;
2362 }
2363 } 2365 }
2364 2366
2365 return force; 2367 return force;
@@ -2368,25 +2370,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 public LSL_Integer llTarget(LSL_Vector position, double range) 2370 public LSL_Integer llTarget(LSL_Vector position, double range)
2369 { 2371 {
2370 m_host.AddScriptLPS(1); 2372 m_host.AddScriptLPS(1);
2371 return m_host.registerTargetWaypoint(new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2373 return m_host.ParentGroup.registerTargetWaypoint(
2374 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range);
2372 } 2375 }
2373 2376
2374 public void llTargetRemove(int number) 2377 public void llTargetRemove(int number)
2375 { 2378 {
2376 m_host.AddScriptLPS(1); 2379 m_host.AddScriptLPS(1);
2377 m_host.unregisterTargetWaypoint(number); 2380 m_host.ParentGroup.unregisterTargetWaypoint(number);
2378 } 2381 }
2379 2382
2380 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2383 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2381 { 2384 {
2382 m_host.AddScriptLPS(1); 2385 m_host.AddScriptLPS(1);
2383 return m_host.registerRotTargetWaypoint(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); 2386 return m_host.ParentGroup.registerRotTargetWaypoint(
2387 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2384 } 2388 }
2385 2389
2386 public void llRotTargetRemove(int number) 2390 public void llRotTargetRemove(int number)
2387 { 2391 {
2388 m_host.AddScriptLPS(1); 2392 m_host.AddScriptLPS(1);
2389 m_host.unregisterRotTargetWaypoint(number); 2393 m_host.ParentGroup.unregisterRotTargetWaypoint(number);
2390 } 2394 }
2391 2395
2392 public void llMoveToTarget(LSL_Vector target, double tau) 2396 public void llMoveToTarget(LSL_Vector target, double tau)
@@ -2429,7 +2433,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2429 public LSL_Vector llGetTorque() 2433 public LSL_Vector llGetTorque()
2430 { 2434 {
2431 m_host.AddScriptLPS(1); 2435 m_host.AddScriptLPS(1);
2432 Vector3 torque = m_host.GetTorque(); 2436 Vector3 torque = m_host.ParentGroup.GetTorque();
2433 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2437 return new LSL_Vector(torque.X,torque.Y,torque.Z);
2434 } 2438 }
2435 2439
@@ -2443,7 +2447,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2443 public LSL_Vector llGetVel() 2447 public LSL_Vector llGetVel()
2444 { 2448 {
2445 m_host.AddScriptLPS(1); 2449 m_host.AddScriptLPS(1);
2446 return new LSL_Vector(m_host.Velocity.X, m_host.Velocity.Y, m_host.Velocity.Z); 2450
2451 Vector3 vel;
2452
2453 if (m_host.ParentGroup.IsAttachment)
2454 {
2455 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2456 vel = avatar.Velocity;
2457 }
2458 else
2459 {
2460 vel = m_host.Velocity;
2461 }
2462
2463 return new LSL_Vector(vel.X, vel.Y, vel.Z);
2447 } 2464 }
2448 2465
2449 public LSL_Vector llGetAccel() 2466 public LSL_Vector llGetAccel()
@@ -2739,10 +2756,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2739 /// negative (indicating end-relative) and may be inverted, 2756 /// negative (indicating end-relative) and may be inverted,
2740 /// i.e. end < start. 2757 /// i.e. end < start.
2741 /// </summary> 2758 /// </summary>
2742
2743 public LSL_String llDeleteSubString(string src, int start, int end) 2759 public LSL_String llDeleteSubString(string src, int start, int end)
2744 { 2760 {
2745
2746 m_host.AddScriptLPS(1); 2761 m_host.AddScriptLPS(1);
2747 2762
2748 // Normalize indices (if negative). 2763 // Normalize indices (if negative).
@@ -2822,10 +2837,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2822 /// which case it is end-relative. The index may exceed either 2837 /// which case it is end-relative. The index may exceed either
2823 /// string bound, with the result being a concatenation. 2838 /// string bound, with the result being a concatenation.
2824 /// </summary> 2839 /// </summary>
2825
2826 public LSL_String llInsertString(string dest, int index, string src) 2840 public LSL_String llInsertString(string dest, int index, string src)
2827 { 2841 {
2828
2829 m_host.AddScriptLPS(1); 2842 m_host.AddScriptLPS(1);
2830 2843
2831 // Normalize indices (if negative). 2844 // Normalize indices (if negative).
@@ -2983,8 +2996,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2983 // If either of these are null, then there was an unknown error. 2996 // If either of these are null, then there was an unknown error.
2984 if (new_group == null) 2997 if (new_group == null)
2985 continue; 2998 continue;
2986 if (new_group.RootPart == null)
2987 continue;
2988 2999
2989 // objects rezzed with this method are die_at_edge by default. 3000 // objects rezzed with this method are die_at_edge by default.
2990 new_group.RootPart.SetDieAtEdge(true); 3001 new_group.RootPart.SetDieAtEdge(true);
@@ -3239,8 +3250,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3239 SceneObjectGroup grp = m_host.ParentGroup; 3250 SceneObjectGroup grp = m_host.ParentGroup;
3240 3251
3241 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3252 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
3242 3253 if (presence.Scene.AttachmentsModule != null)
3243 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false); 3254 {
3255 presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false);
3256 }
3244 } 3257 }
3245 } 3258 }
3246 3259
@@ -3248,7 +3261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3248 { 3261 {
3249 m_host.AddScriptLPS(1); 3262 m_host.AddScriptLPS(1);
3250 3263
3251 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) 3264 if (m_host.ParentGroup.AttachmentPoint == 0)
3252 return; 3265 return;
3253 3266
3254 TaskInventoryItem item; 3267 TaskInventoryItem item;
@@ -3288,7 +3301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3288 3301
3289 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3302 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3290 if (attachmentsModule != null) 3303 if (attachmentsModule != null)
3291 attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); 3304 attachmentsModule.DetachSingleAttachmentToInv(itemID, presence.ControllingClient);
3292 } 3305 }
3293 3306
3294 public void llTakeCamera(string avatar) 3307 public void llTakeCamera(string avatar)
@@ -3449,12 +3462,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3449 public void llSetBuoyancy(double buoyancy) 3462 public void llSetBuoyancy(double buoyancy)
3450 { 3463 {
3451 m_host.AddScriptLPS(1); 3464 m_host.AddScriptLPS(1);
3452 if (m_host.ParentGroup != null) 3465
3466 if (!m_host.ParentGroup.IsDeleted)
3453 { 3467 {
3454 if (!m_host.ParentGroup.IsDeleted) 3468 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
3455 {
3456 m_host.ParentGroup.RootPart.Buoyancy = (float)buoyancy;
3457 }
3458 } 3469 }
3459 } 3470 }
3460 3471
@@ -3683,7 +3694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3683 3694
3684 m_host.AddScriptLPS(1); 3695 m_host.AddScriptLPS(1);
3685 3696
3686 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.RootPart.AttachedAvatar) 3697 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
3687 { 3698 {
3688 // When attached, certain permissions are implicit if requested from owner 3699 // When attached, certain permissions are implicit if requested from owner
3689 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3700 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
@@ -3909,7 +3920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3909 3920
3910 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 3921 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3911 3922
3912 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3923 if (targetPart.ParentGroup.AttachmentPoint != 0)
3913 return; // Fail silently if attached 3924 return; // Fail silently if attached
3914 3925
3915 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID) 3926 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
@@ -3967,7 +3978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 3978
3968 SceneObjectGroup parentPrim = m_host.ParentGroup; 3979 SceneObjectGroup parentPrim = m_host.ParentGroup;
3969 3980
3970 if (parentPrim.RootPart.AttachmentPoint != 0) 3981 if (parentPrim.AttachmentPoint != 0)
3971 return; // Fail silently if attached 3982 return; // Fail silently if attached
3972 SceneObjectPart childPrim = null; 3983 SceneObjectPart childPrim = null;
3973 3984
@@ -4075,7 +4086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4075 } 4086 }
4076 4087
4077 SceneObjectGroup parentPrim = m_host.ParentGroup; 4088 SceneObjectGroup parentPrim = m_host.ParentGroup;
4078 if (parentPrim.RootPart.AttachmentPoint != 0) 4089 if (parentPrim.AttachmentPoint != 0)
4079 return; // Fail silently if attached 4090 return; // Fail silently if attached
4080 4091
4081 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4092 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
@@ -4311,7 +4322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4311 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
4312 m_host.UUID, m_host.Name+", an object owned by "+ 4323 m_host.UUID, m_host.Name+", an object owned by "+
4313 resolveName(m_host.OwnerID)+",", destId, 4324 resolveName(m_host.OwnerID)+",", destId,
4314 (byte)InstantMessageDialog.InventoryOffered, 4325 (byte)InstantMessageDialog.TaskInventoryOffered,
4315 false, objName+"\n"+m_host.Name+" is located at "+ 4326 false, objName+"\n"+m_host.Name+" is located at "+
4316 World.RegionInfo.RegionName+" "+ 4327 World.RegionInfo.RegionName+" "+
4317 m_host.AbsolutePosition.ToString(), 4328 m_host.AbsolutePosition.ToString(),
@@ -4749,7 +4760,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4749 return; 4760 return;
4750 4761
4751 // Object not pushable. Not an attachment and has no physics component 4762 // Object not pushable. Not an attachment and has no physics component
4752 if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) 4763 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4753 return; 4764 return;
4754 4765
4755 PusheePos = pusheeob.AbsolutePosition; 4766 PusheePos = pusheeob.AbsolutePosition;
@@ -6279,7 +6290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6279 public LSL_Integer llGetAttached() 6290 public LSL_Integer llGetAttached()
6280 { 6291 {
6281 m_host.AddScriptLPS(1); 6292 m_host.AddScriptLPS(1);
6282 return m_host.ParentGroup.RootPart.AttachmentPoint; 6293 return m_host.ParentGroup.AttachmentPoint;
6283 } 6294 }
6284 6295
6285 public virtual LSL_Integer llGetFreeMemory() 6296 public virtual LSL_Integer llGetFreeMemory()
@@ -6663,12 +6674,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6663 public void llSetVehicleType(int type) 6674 public void llSetVehicleType(int type)
6664 { 6675 {
6665 m_host.AddScriptLPS(1); 6676 m_host.AddScriptLPS(1);
6666 if (m_host.ParentGroup != null) 6677
6678 if (!m_host.ParentGroup.IsDeleted)
6667 { 6679 {
6668 if (!m_host.ParentGroup.IsDeleted) 6680 m_host.ParentGroup.RootPart.SetVehicleType(type);
6669 {
6670 m_host.ParentGroup.RootPart.SetVehicleType(type);
6671 }
6672 } 6681 }
6673 } 6682 }
6674 6683
@@ -6678,12 +6687,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6678 { 6687 {
6679 m_host.AddScriptLPS(1); 6688 m_host.AddScriptLPS(1);
6680 6689
6681 if (m_host.ParentGroup != null) 6690 if (!m_host.ParentGroup.IsDeleted)
6682 { 6691 {
6683 if (!m_host.ParentGroup.IsDeleted) 6692 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6684 {
6685 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6686 }
6687 } 6693 }
6688 } 6694 }
6689 6695
@@ -6692,13 +6698,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6692 public void llSetVehicleVectorParam(int param, LSL_Vector vec) 6698 public void llSetVehicleVectorParam(int param, LSL_Vector vec)
6693 { 6699 {
6694 m_host.AddScriptLPS(1); 6700 m_host.AddScriptLPS(1);
6695 if (m_host.ParentGroup != null) 6701
6702 if (!m_host.ParentGroup.IsDeleted)
6696 { 6703 {
6697 if (!m_host.ParentGroup.IsDeleted) 6704 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6698 { 6705 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6699 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6700 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6701 }
6702 } 6706 }
6703 } 6707 }
6704 6708
@@ -6707,37 +6711,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6707 public void llSetVehicleRotationParam(int param, LSL_Rotation rot) 6711 public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
6708 { 6712 {
6709 m_host.AddScriptLPS(1); 6713 m_host.AddScriptLPS(1);
6710 if (m_host.ParentGroup != null) 6714
6715 if (!m_host.ParentGroup.IsDeleted)
6711 { 6716 {
6712 if (!m_host.ParentGroup.IsDeleted) 6717 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot));
6713 {
6714 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param,
6715 Rot2Quaternion(rot));
6716 }
6717 } 6718 }
6718 } 6719 }
6719 6720
6720 public void llSetVehicleFlags(int flags) 6721 public void llSetVehicleFlags(int flags)
6721 { 6722 {
6722 m_host.AddScriptLPS(1); 6723 m_host.AddScriptLPS(1);
6723 if (m_host.ParentGroup != null) 6724
6725 if (!m_host.ParentGroup.IsDeleted)
6724 { 6726 {
6725 if (!m_host.ParentGroup.IsDeleted) 6727 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6726 {
6727 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6728 }
6729 } 6728 }
6730 } 6729 }
6731 6730
6732 public void llRemoveVehicleFlags(int flags) 6731 public void llRemoveVehicleFlags(int flags)
6733 { 6732 {
6734 m_host.AddScriptLPS(1); 6733 m_host.AddScriptLPS(1);
6735 if (m_host.ParentGroup != null) 6734
6735 if (!m_host.ParentGroup.IsDeleted)
6736 { 6736 {
6737 if (!m_host.ParentGroup.IsDeleted) 6737 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6738 {
6739 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6740 }
6741 } 6738 }
6742 } 6739 }
6743 6740
@@ -6891,20 +6888,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6891 public void llVolumeDetect(int detect) 6888 public void llVolumeDetect(int detect)
6892 { 6889 {
6893 m_host.AddScriptLPS(1); 6890 m_host.AddScriptLPS(1);
6894 if (m_host.ParentGroup != null) 6891
6895 { 6892 if (!m_host.ParentGroup.IsDeleted)
6896 if (!m_host.ParentGroup.IsDeleted) 6893 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0);
6897 {
6898 m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0);
6899 }
6900 }
6901 } 6894 }
6902 6895
6903 /// <summary> 6896 /// <summary>
6904 /// This is a depecated function so this just replicates the result of 6897 /// This is a depecated function so this just replicates the result of
6905 /// invoking it in SL 6898 /// invoking it in SL
6906 /// </summary> 6899 /// </summary>
6907
6908 public void llRemoteLoadScript(string target, string name, int running, int start_param) 6900 public void llRemoteLoadScript(string target, string name, int running, int start_param)
6909 { 6901 {
6910 m_host.AddScriptLPS(1); 6902 m_host.AddScriptLPS(1);
@@ -7046,8 +7038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7046 return Util.SHA1Hash(src, Encoding.UTF8).ToLower(); 7038 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7047 } 7039 }
7048 7040
7049 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7041 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7050 { 7042 {
7043 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7051 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7044 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7045 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7053 return shapeBlock; 7046 return shapeBlock;
@@ -7059,7 +7052,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7059 { 7052 {
7060 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; 7053 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
7061 } 7054 }
7062 shapeBlock.ProfileCurve = (byte)holeshape; 7055 shapeBlock.PathCurve = pathcurve;
7056 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape.
7057 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape.
7063 if (cut.x < 0f) 7058 if (cut.x < 0f)
7064 { 7059 {
7065 cut.x = 0f; 7060 cut.x = 0f;
@@ -7091,9 +7086,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7091 { 7086 {
7092 hollow = 0f; 7087 hollow = 0f;
7093 } 7088 }
7094 if (hollow > 0.95) 7089 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a
7090 // Box or Tube) and the hole shape is a square, hollow is limited to
7091 // a max of 70%. The viewer performs its own check on this value but
7092 // we need to do it here also so llGetPrimitiveParams can have access
7093 // to the correct value.
7094 if (profileshape != (byte)ProfileCurve.Square &&
7095 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE)
7095 { 7096 {
7096 hollow = 0.95f; 7097 if (hollow > 0.70f)
7098 {
7099 hollow = 0.70f;
7100 }
7101 }
7102 // Otherwise, hollow is limited to 95%.
7103 else
7104 {
7105 if (hollow > 0.95f)
7106 {
7107 hollow = 0.95f;
7108 }
7097 } 7109 }
7098 shapeBlock.ProfileHollow = (ushort)(50000 * hollow); 7110 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
7099 if (twist.x < -1.0f) 7111 if (twist.x < -1.0f)
@@ -7112,28 +7124,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7112 { 7124 {
7113 twist.y = 1.0f; 7125 twist.y = 1.0f;
7114 } 7126 }
7115 shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); 7127 // A fairly large precision error occurs for some calculations,
7116 shapeBlock.PathTwist = (sbyte)(100 * twist.y); 7128 // if a float or double is directly cast to a byte or sbyte
7129 // variable, in both .Net and Mono. In .Net, coding
7130 // "(sbyte)(float)(some expression)" corrects the precision
7131 // errors. But this does not work for Mono. This longer coding
7132 // form of creating a tempoary float variable from the
7133 // expression first, then casting that variable to a byte or
7134 // sbyte, works for both .Net and Mono. These types of
7135 // assignments occur in SetPrimtiveBlockShapeParams and
7136 // SetPrimitiveShapeParams in support of llSetPrimitiveParams.
7137 tempFloat = (float)(100.0d * twist.x);
7138 shapeBlock.PathTwistBegin = (sbyte)tempFloat;
7139 tempFloat = (float)(100.0d * twist.y);
7140 shapeBlock.PathTwist = (sbyte)tempFloat;
7117 7141
7118 shapeBlock.ObjectLocalID = part.LocalId; 7142 shapeBlock.ObjectLocalID = part.LocalId;
7119 7143
7120 // retain pathcurve
7121 shapeBlock.PathCurve = part.Shape.PathCurve;
7122
7123 part.Shape.SculptEntry = false; 7144 part.Shape.SculptEntry = false;
7124 return shapeBlock; 7145 return shapeBlock;
7125 } 7146 }
7126 7147
7127 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7148 // Prim type box, cylinder and prism.
7149 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
7128 { 7150 {
7129 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7151 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7130 return; 7152 return;
7131 7153
7154 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7132 ObjectShapePacket.ObjectDataBlock shapeBlock; 7155 ObjectShapePacket.ObjectDataBlock shapeBlock;
7133 7156
7134 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7157 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7135
7136 shapeBlock.ProfileCurve += fudge;
7137 7158
7138 if (taper_b.x < 0f) 7159 if (taper_b.x < 0f)
7139 { 7160 {
@@ -7151,8 +7172,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7151 { 7172 {
7152 taper_b.y = 2f; 7173 taper_b.y = 2f;
7153 } 7174 }
7154 shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); 7175 tempFloat = (float)(100.0d * (2.0d - taper_b.x));
7155 shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); 7176 shapeBlock.PathScaleX = (byte)tempFloat;
7177 tempFloat = (float)(100.0d * (2.0d - taper_b.y));
7178 shapeBlock.PathScaleY = (byte)tempFloat;
7156 if (topshear.x < -0.5f) 7179 if (topshear.x < -0.5f)
7157 { 7180 {
7158 topshear.x = -0.5f; 7181 topshear.x = -0.5f;
@@ -7169,28 +7192,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7169 { 7192 {
7170 topshear.y = 0.5f; 7193 topshear.y = 0.5f;
7171 } 7194 }
7172 shapeBlock.PathShearX = (byte)(100 * topshear.x); 7195 tempFloat = (float)(100.0d * topshear.x);
7173 shapeBlock.PathShearY = (byte)(100 * topshear.y); 7196 shapeBlock.PathShearX = (byte)tempFloat;
7197 tempFloat = (float)(100.0d * topshear.y);
7198 shapeBlock.PathShearY = (byte)tempFloat;
7174 7199
7175 part.Shape.SculptEntry = false; 7200 part.Shape.SculptEntry = false;
7176 part.UpdateShape(shapeBlock); 7201 part.UpdateShape(shapeBlock);
7177 } 7202 }
7178 7203
7179 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7204 // Prim type sphere.
7205 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7180 { 7206 {
7181 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7207 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7182 return; 7208 return;
7183 7209
7184 ObjectShapePacket.ObjectDataBlock shapeBlock; 7210 ObjectShapePacket.ObjectDataBlock shapeBlock;
7185 7211
7186 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7212 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7187 7213
7188 // profile/path swapped for a sphere 7214 // profile/path swapped for a sphere
7189 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7215 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7190 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7216 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7191 7217
7192 shapeBlock.ProfileCurve += fudge;
7193
7194 shapeBlock.PathScaleX = 100; 7218 shapeBlock.PathScaleX = 100;
7195 shapeBlock.PathScaleY = 100; 7219 shapeBlock.PathScaleY = 100;
7196 7220
@@ -7221,16 +7245,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 part.UpdateShape(shapeBlock); 7245 part.UpdateShape(shapeBlock);
7222 } 7246 }
7223 7247
7224 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) 7248 // Prim type torus, tube and ring.
7249 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
7225 { 7250 {
7226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7251 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7227 return; 7252 return;
7228 7253
7254 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7229 ObjectShapePacket.ObjectDataBlock shapeBlock; 7255 ObjectShapePacket.ObjectDataBlock shapeBlock;
7230 7256
7231 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7257 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7232
7233 shapeBlock.ProfileCurve += fudge;
7234 7258
7235 // profile/path swapped for a torrus, tube, ring 7259 // profile/path swapped for a torrus, tube, ring
7236 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7260 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
@@ -7252,8 +7276,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7252 { 7276 {
7253 holesize.y = 0.5f; 7277 holesize.y = 0.5f;
7254 } 7278 }
7255 shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); 7279 tempFloat = (float)(100.0d * (2.0d - holesize.x));
7256 shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); 7280 shapeBlock.PathScaleX = (byte)tempFloat;
7281 tempFloat = (float)(100.0d * (2.0d - holesize.y));
7282 shapeBlock.PathScaleY = (byte)tempFloat;
7257 if (topshear.x < -0.5f) 7283 if (topshear.x < -0.5f)
7258 { 7284 {
7259 topshear.x = -0.5f; 7285 topshear.x = -0.5f;
@@ -7270,8 +7296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7270 { 7296 {
7271 topshear.y = 0.5f; 7297 topshear.y = 0.5f;
7272 } 7298 }
7273 shapeBlock.PathShearX = (byte)(100 * topshear.x); 7299 tempFloat = (float)(100.0d * topshear.x);
7274 shapeBlock.PathShearY = (byte)(100 * topshear.y); 7300 shapeBlock.PathShearX = (byte)tempFloat;
7301 tempFloat = (float)(100.0d * topshear.y);
7302 shapeBlock.PathShearY = (byte)tempFloat;
7275 if (profilecut.x < 0f) 7303 if (profilecut.x < 0f)
7276 { 7304 {
7277 profilecut.x = 0f; 7305 profilecut.x = 0f;
@@ -7315,8 +7343,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7315 { 7343 {
7316 taper_a.y = 1f; 7344 taper_a.y = 1f;
7317 } 7345 }
7318 shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); 7346 tempFloat = (float)(100.0d * taper_a.x);
7319 shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); 7347 shapeBlock.PathTaperX = (sbyte)tempFloat;
7348 tempFloat = (float)(100.0d * taper_a.y);
7349 shapeBlock.PathTaperY = (sbyte)tempFloat;
7320 if (revolutions < 1f) 7350 if (revolutions < 1f)
7321 { 7351 {
7322 revolutions = 1f; 7352 revolutions = 1f;
@@ -7325,7 +7355,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7325 { 7355 {
7326 revolutions = 4f; 7356 revolutions = 4f;
7327 } 7357 }
7328 shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); 7358 tempFloat = 66.66667f * (revolutions - 1.0f);
7359 shapeBlock.PathRevolutions = (byte)tempFloat;
7329 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 7360 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
7330 if (radiusoffset < 0f) 7361 if (radiusoffset < 0f)
7331 { 7362 {
@@ -7335,7 +7366,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7335 { 7366 {
7336 radiusoffset = 1f; 7367 radiusoffset = 1f;
7337 } 7368 }
7338 shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); 7369 tempFloat = 100.0f * radiusoffset;
7370 shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
7339 if (skew < -0.95f) 7371 if (skew < -0.95f)
7340 { 7372 {
7341 skew = -0.95f; 7373 skew = -0.95f;
@@ -7344,13 +7376,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7344 { 7376 {
7345 skew = 0.95f; 7377 skew = 0.95f;
7346 } 7378 }
7347 shapeBlock.PathSkew = (sbyte)(100 * skew); 7379 tempFloat = 100.0f * skew;
7380 shapeBlock.PathSkew = (sbyte)tempFloat;
7348 7381
7349 part.Shape.SculptEntry = false; 7382 part.Shape.SculptEntry = false;
7350 part.UpdateShape(shapeBlock); 7383 part.UpdateShape(shapeBlock);
7351 } 7384 }
7352 7385
7353 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7386 // Prim type sculpt.
7387 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7354 { 7388 {
7355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7389 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7356 return; 7390 return;
@@ -7366,6 +7400,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7366 if (sculptId == UUID.Zero) 7400 if (sculptId == UUID.Zero)
7367 return; 7401 return;
7368 7402
7403 shapeBlock.PathCurve = pathcurve;
7369 shapeBlock.ObjectLocalID = part.LocalId; 7404 shapeBlock.ObjectLocalID = part.LocalId;
7370 shapeBlock.PathScaleX = 100; 7405 shapeBlock.PathScaleX = 100;
7371 shapeBlock.PathScaleY = 150; 7406 shapeBlock.PathScaleY = 150;
@@ -7379,9 +7414,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7379 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7414 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7380 } 7415 }
7381 7416
7382 // retain pathcurve
7383 shapeBlock.PathCurve = part.Shape.PathCurve;
7384
7385 part.Shape.SetSculptProperties((byte)type, sculptId); 7417 part.Shape.SetSculptProperties((byte)type, sculptId);
7386 part.Shape.SculptEntry = true; 7418 part.Shape.SculptEntry = true;
7387 part.UpdateShape(shapeBlock); 7419 part.UpdateShape(shapeBlock);
@@ -7518,15 +7550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7518 else 7550 else
7519 { 7551 {
7520 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7552 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7521 SceneObjectGroup group = part.ParentGroup; 7553 SceneObjectPart rootPart = part.ParentGroup.RootPart;
7522 if (group != null) // a bit paranoid, maybe 7554 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7523 {
7524 SceneObjectPart rootPart = group.RootPart;
7525 if (rootPart != null) // again, better safe than sorry
7526 {
7527 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7528 }
7529 }
7530 } 7555 }
7531 7556
7532 break; 7557 break;
@@ -7561,8 +7586,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7561 taper_b = rules.GetVector3Item(idx++); 7586 taper_b = rules.GetVector3Item(idx++);
7562 topshear = rules.GetVector3Item(idx++); 7587 topshear = rules.GetVector3Item(idx++);
7563 7588
7564 part.Shape.PathCurve = (byte)Extrusion.Straight; 7589 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7565 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 1); 7590 (byte)ProfileShape.Square, (byte)Extrusion.Straight);
7566 break; 7591 break;
7567 7592
7568 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: 7593 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
@@ -7575,9 +7600,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7575 twist = rules.GetVector3Item(idx++); 7600 twist = rules.GetVector3Item(idx++);
7576 taper_b = rules.GetVector3Item(idx++); 7601 taper_b = rules.GetVector3Item(idx++);
7577 topshear = rules.GetVector3Item(idx++); 7602 topshear = rules.GetVector3Item(idx++);
7578 part.Shape.ProfileShape = ProfileShape.Circle; 7603 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7579 part.Shape.PathCurve = (byte)Extrusion.Straight; 7604 (byte)ProfileShape.Circle, (byte)Extrusion.Straight);
7580 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 0);
7581 break; 7605 break;
7582 7606
7583 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: 7607 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
@@ -7590,8 +7614,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7590 twist = rules.GetVector3Item(idx++); 7614 twist = rules.GetVector3Item(idx++);
7591 taper_b = rules.GetVector3Item(idx++); 7615 taper_b = rules.GetVector3Item(idx++);
7592 topshear = rules.GetVector3Item(idx++); 7616 topshear = rules.GetVector3Item(idx++);
7593 part.Shape.PathCurve = (byte)Extrusion.Straight; 7617 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7594 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 3); 7618 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight);
7595 break; 7619 break;
7596 7620
7597 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: 7621 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
@@ -7603,8 +7627,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 hollow = (float)rules.GetLSLFloatItem(idx++); 7627 hollow = (float)rules.GetLSLFloatItem(idx++);
7604 twist = rules.GetVector3Item(idx++); 7628 twist = rules.GetVector3Item(idx++);
7605 taper_b = rules.GetVector3Item(idx++); // dimple 7629 taper_b = rules.GetVector3Item(idx++); // dimple
7606 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7630 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b,
7607 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 5); 7631 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1);
7608 break; 7632 break;
7609 7633
7610 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: 7634 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
@@ -7622,9 +7646,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7622 revolutions = (float)rules.GetLSLFloatItem(idx++); 7646 revolutions = (float)rules.GetLSLFloatItem(idx++);
7623 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7647 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7624 skew = (float)rules.GetLSLFloatItem(idx++); 7648 skew = (float)rules.GetLSLFloatItem(idx++);
7625 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7626 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7649 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7627 revolutions, radiusoffset, skew, 0); 7650 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1);
7628 break; 7651 break;
7629 7652
7630 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: 7653 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
@@ -7642,9 +7665,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7642 revolutions = (float)rules.GetLSLFloatItem(idx++); 7665 revolutions = (float)rules.GetLSLFloatItem(idx++);
7643 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7666 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7644 skew = (float)rules.GetLSLFloatItem(idx++); 7667 skew = (float)rules.GetLSLFloatItem(idx++);
7645 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7646 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7668 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7647 revolutions, radiusoffset, skew, 1); 7669 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1);
7648 break; 7670 break;
7649 7671
7650 case (int)ScriptBaseClass.PRIM_TYPE_RING: 7672 case (int)ScriptBaseClass.PRIM_TYPE_RING:
@@ -7662,9 +7684,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7662 revolutions = (float)rules.GetLSLFloatItem(idx++); 7684 revolutions = (float)rules.GetLSLFloatItem(idx++);
7663 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7685 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7664 skew = (float)rules.GetLSLFloatItem(idx++); 7686 skew = (float)rules.GetLSLFloatItem(idx++);
7665 part.Shape.PathCurve = (byte)Extrusion.Curve1;
7666 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7687 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7667 revolutions, radiusoffset, skew, 3); 7688 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1);
7668 break; 7689 break;
7669 7690
7670 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: 7691 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
@@ -7673,8 +7694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7673 7694
7674 string map = rules.Data[idx++].ToString(); 7695 string map = rules.Data[idx++].ToString();
7675 face = (int)rules.GetLSLIntegerItem(idx++); // type 7696 face = (int)rules.GetLSLIntegerItem(idx++); // type
7676 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7697 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1);
7677 SetPrimitiveShapeParams(part, map, face);
7678 break; 7698 break;
7679 } 7699 }
7680 7700
@@ -7779,18 +7799,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7779 break; 7799 break;
7780 7800
7781 case (int)ScriptBaseClass.PRIM_PHANTOM: 7801 case (int)ScriptBaseClass.PRIM_PHANTOM:
7782 if (remain < 1) 7802 if (remain < 1)
7783 return; 7803 return;
7784 7804
7785 string ph = rules.Data[idx++].ToString(); 7805 string ph = rules.Data[idx++].ToString();
7786 bool phantom; 7806 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
7787 7807
7788 if (ph.Equals("1"))
7789 phantom = true;
7790 else
7791 phantom = false;
7792
7793 part.ScriptSetPhantomStatus(phantom);
7794 break; 7808 break;
7795 7809
7796 case (int)ScriptBaseClass.PRIM_PHYSICS: 7810 case (int)ScriptBaseClass.PRIM_PHYSICS:
@@ -7811,14 +7825,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7811 if (remain < 1) 7825 if (remain < 1)
7812 return; 7826 return;
7813 string temp = rules.Data[idx++].ToString(); 7827 string temp = rules.Data[idx++].ToString();
7814 bool tempOnRez;
7815 7828
7816 if (temp.Equals("1")) 7829 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
7817 tempOnRez = true;
7818 else
7819 tempOnRez = false;
7820 7830
7821 part.ScriptSetTemporaryStatus(tempOnRez);
7822 break; 7831 break;
7823 7832
7824 case (int)ScriptBaseClass.PRIM_TEXGEN: 7833 case (int)ScriptBaseClass.PRIM_TEXGEN:
@@ -7983,9 +7992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7983 { 7992 {
7984 m_host.AddScriptLPS(1); 7993 m_host.AddScriptLPS(1);
7985 Quaternion q; 7994 Quaternion q;
7986 if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) 7995 if (m_host.ParentGroup.AttachmentPoint != 0)
7987 { 7996 {
7988 ScenePresence avatar = World.GetScenePresence(m_host.AttachedAvatar); 7997 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
7989 if (avatar != null) 7998 if (avatar != null)
7990 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 7999 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
7991 q = avatar.CameraRotation; // Mouselook 8000 q = avatar.CameraRotation; // Mouselook
@@ -8055,7 +8064,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8055 // the UUID with the avatar UUID and report it's bounding box 8064 // the UUID with the avatar UUID and report it's bounding box
8056 SceneObjectPart part = World.GetSceneObjectPart(objID); 8065 SceneObjectPart part = World.GetSceneObjectPart(objID);
8057 if (part != null && part.ParentGroup.IsAttachment) 8066 if (part != null && part.ParentGroup.IsAttachment)
8058 objID = part.ParentGroup.RootPart.AttachedAvatar; 8067 objID = part.ParentGroup.AttachedAvatar;
8059 8068
8060 // Find out if this is an avatar ID. If so, return it's box 8069 // Find out if this is an avatar ID. If so, return it's box
8061 ScenePresence presence = World.GetScenePresence(objID); 8070 ScenePresence presence = World.GetScenePresence(objID);
@@ -8238,7 +8247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8238 case ScriptBaseClass.PRIM_TYPE_BOX: 8247 case ScriptBaseClass.PRIM_TYPE_BOX:
8239 case ScriptBaseClass.PRIM_TYPE_CYLINDER: 8248 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
8240 case ScriptBaseClass.PRIM_TYPE_PRISM: 8249 case ScriptBaseClass.PRIM_TYPE_PRISM:
8241 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8250 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8242 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8251 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8243 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8252 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8244 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8253 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -8247,7 +8256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8247 break; 8256 break;
8248 8257
8249 case ScriptBaseClass.PRIM_TYPE_SPHERE: 8258 case ScriptBaseClass.PRIM_TYPE_SPHERE:
8250 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8259 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8251 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8260 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
8252 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8261 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8253 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8262 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -8263,7 +8272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8263 case ScriptBaseClass.PRIM_TYPE_TUBE: 8272 case ScriptBaseClass.PRIM_TYPE_TUBE:
8264 case ScriptBaseClass.PRIM_TYPE_TORUS: 8273 case ScriptBaseClass.PRIM_TYPE_TORUS:
8265 // holeshape 8274 // holeshape
8266 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8275 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8267 8276
8268 // cut 8277 // cut
8269 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8278 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
@@ -8287,10 +8296,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8287 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8296 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8288 8297
8289 // float revolutions 8298 // float revolutions
8290 res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned 8299 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8291 // byte is being used to represent the entire 8300 // Slightly inaccurate, because an unsigned byte is being used to represent
8292 // range of floating-point values from 1.0 8301 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8293 // through 4.0 (which is how SL does it). 8302 // SL does it).
8303 //
8304 // Using these formulas to store and retrieve PathRevolutions, it is not
8305 // possible to use all values between 1.00 and 4.00. For instance, you can't
8306 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8307 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8308 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8309 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8310 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8311 // such as 1.10. So, SL must store and retreive the actual user input rather
8312 // than only storing the encoded value.
8294 8313
8295 // float radiusoffset 8314 // float radiusoffset
8296 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); 8315 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
@@ -10085,7 +10104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10104 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
10086 if (detectedParams == null) 10105 if (detectedParams == null)
10087 { 10106 {
10088 if (m_host.IsAttachment == true) 10107 if (m_host.ParentGroup.IsAttachment == true)
10089 { 10108 {
10090 detectedParams = new DetectParams(); 10109 detectedParams = new DetectParams();
10091 detectedParams.Key = m_host.OwnerID; 10110 detectedParams.Key = m_host.OwnerID;
@@ -10666,6 +10685,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10666 public LSL_List llGetObjectDetails(string id, LSL_List args) 10685 public LSL_List llGetObjectDetails(string id, LSL_List args)
10667 { 10686 {
10668 m_host.AddScriptLPS(1); 10687 m_host.AddScriptLPS(1);
10688
10669 LSL_List ret = new LSL_List(); 10689 LSL_List ret = new LSL_List();
10670 UUID key = new UUID(); 10690 UUID key = new UUID();
10671 if (UUID.TryParse(id, out key)) 10691 if (UUID.TryParse(id, out key))
@@ -10676,72 +10696,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10676 { 10696 {
10677 foreach (object o in args.Data) 10697 foreach (object o in args.Data)
10678 { 10698 {
10679 switch (o.ToString()) 10699 switch (int.Parse(o.ToString()))
10680 { 10700 {
10681 case "1": 10701 case ScriptBaseClass.OBJECT_NAME:
10682 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname)); 10702 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname));
10683 break; 10703 break;
10684 case "2": 10704 case ScriptBaseClass.OBJECT_DESC:
10685 ret.Add(new LSL_String("")); 10705 ret.Add(new LSL_String(""));
10686 break; 10706 break;
10687 case "3": 10707 case ScriptBaseClass.OBJECT_POS:
10688 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10708 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
10689 break; 10709 break;
10690 case "4": 10710 case ScriptBaseClass.OBJECT_ROT:
10691 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 10711 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W));
10692 break; 10712 break;
10693 case "5": 10713 case ScriptBaseClass.OBJECT_VELOCITY:
10694 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10714 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
10695 break; 10715 break;
10696 case "6": 10716 case ScriptBaseClass.OBJECT_OWNER:
10697 ret.Add(new LSL_String(id)); 10717 ret.Add(new LSL_String(id));
10698 break; 10718 break;
10699 case "7": 10719 case ScriptBaseClass.OBJECT_GROUP:
10700 ret.Add(new LSL_String(UUID.Zero.ToString())); 10720 ret.Add(new LSL_String(UUID.Zero.ToString()));
10701 break; 10721 break;
10702 case "8": 10722 case ScriptBaseClass.OBJECT_CREATOR:
10703 ret.Add(new LSL_String(UUID.Zero.ToString())); 10723 ret.Add(new LSL_String(UUID.Zero.ToString()));
10704 break; 10724 break;
10705 } 10725 }
10706 } 10726 }
10727
10707 return ret; 10728 return ret;
10708 } 10729 }
10730
10709 SceneObjectPart obj = World.GetSceneObjectPart(key); 10731 SceneObjectPart obj = World.GetSceneObjectPart(key);
10710 if (obj != null) 10732 if (obj != null)
10711 { 10733 {
10712 foreach (object o in args.Data) 10734 foreach (object o in args.Data)
10713 { 10735 {
10714 switch (o.ToString()) 10736 switch (int.Parse(o.ToString()))
10715 { 10737 {
10716 case "1": 10738 case ScriptBaseClass.OBJECT_NAME:
10717 ret.Add(new LSL_String(obj.Name)); 10739 ret.Add(new LSL_String(obj.Name));
10718 break; 10740 break;
10719 case "2": 10741 case ScriptBaseClass.OBJECT_DESC:
10720 ret.Add(new LSL_String(obj.Description)); 10742 ret.Add(new LSL_String(obj.Description));
10721 break; 10743 break;
10722 case "3": 10744 case ScriptBaseClass.OBJECT_POS:
10723 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 10745 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z));
10724 break; 10746 break;
10725 case "4": 10747 case ScriptBaseClass.OBJECT_ROT:
10726 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 10748 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W));
10727 break; 10749 break;
10728 case "5": 10750 case ScriptBaseClass.OBJECT_VELOCITY:
10729 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 10751 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z));
10730 break; 10752 break;
10731 case "6": 10753 case ScriptBaseClass.OBJECT_OWNER:
10732 ret.Add(new LSL_String(obj.OwnerID.ToString())); 10754 ret.Add(new LSL_String(obj.OwnerID.ToString()));
10733 break; 10755 break;
10734 case "7": 10756 case ScriptBaseClass.OBJECT_GROUP:
10735 ret.Add(new LSL_String(obj.GroupID.ToString())); 10757 ret.Add(new LSL_String(obj.GroupID.ToString()));
10736 break; 10758 break;
10737 case "8": 10759 case ScriptBaseClass.OBJECT_CREATOR:
10738 ret.Add(new LSL_String(obj.CreatorID.ToString())); 10760 ret.Add(new LSL_String(obj.CreatorID.ToString()));
10739 break; 10761 break;
10740 } 10762 }
10741 } 10763 }
10764
10742 return ret; 10765 return ret;
10743 } 10766 }
10744 } 10767 }
10768
10745 return new LSL_List(); 10769 return new LSL_List();
10746 } 10770 }
10747 10771
@@ -11000,31 +11024,173 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11000 { 11024 {
11001 m_SayShoutCount = 0; 11025 m_SayShoutCount = 0;
11002 } 11026 }
11027 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11028 {
11029 m_host.AddScriptLPS(1);
11030
11031 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z);
11032 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
11033 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);
11034
11035 int count = 0;
11036// int detectPhantom = 0;
11037 int dataFlags = 0;
11038 int rejectTypes = 0;
11039
11040 for (int i = 0; i < options.Length; i += 2)
11041 {
11042 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
11043 {
11044 count = options.GetLSLIntegerItem(i + 1);
11045 }
11046// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
11047// {
11048// detectPhantom = options.GetLSLIntegerItem(i + 1);
11049// }
11050 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
11051 {
11052 dataFlags = options.GetLSLIntegerItem(i + 1);
11053 }
11054 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
11055 {
11056 rejectTypes = options.GetLSLIntegerItem(i + 1);
11057 }
11058 }
11059
11060 LSL_List list = new LSL_List();
11061 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);
11062
11063 double distance = Util.GetDistanceTo(startvector, endvector);
11064
11065 if (distance == 0)
11066 distance = 0.001;
11067
11068 Vector3 posToCheck = startvector;
11069 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
11070
11071 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
11072 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
11073 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
11074 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11075
11076 for (float i = 0; i <= distance; i += 0.1f)
11077 {
11078 posToCheck = startvector + (dir * (i / (float)distance));
11079
11080 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z)
11081 {
11082 ContactResult result = new ContactResult();
11083 result.ConsumerID = 0;
11084 result.Depth = 0;
11085 result.Normal = Vector3.Zero;
11086 result.Pos = posToCheck;
11087 results.Add(result);
11088 checkTerrain = false;
11089 }
11090
11091 if (checkAgents)
11092 {
11093 World.ForEachScenePresence(delegate(ScenePresence sp)
11094 {
11095 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
11096 {
11097 ContactResult result = new ContactResult ();
11098 result.ConsumerID = sp.LocalId;
11099 result.Depth = 0;
11100 result.Normal = Vector3.Zero;
11101 result.Pos = posToCheck;
11102 results.Add(result);
11103 }
11104 });
11105 }
11106 }
11107
11108 int refcount = 0;
11109 foreach (ContactResult result in results)
11110 {
11111 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
11112 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
11113 continue;
11114
11115 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
11116
11117 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
11118 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
11119
11120 if (entity == null)
11121 {
11122 list.Add(UUID.Zero);
11123
11124 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11125 list.Add(0);
11126
11127 list.Add(result.Pos);
11128
11129 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11130 list.Add(result.Normal);
11131
11132 continue; //Can't find it, so add UUID.Zero
11133 }
11134
11135 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
11136 ((ISceneChildEntity)intersection.obj).PhysActor == null)
11137 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
11138
11139 if (entity is SceneObjectPart)
11140 {
11141 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical)
11142 {
11143 if (!checkPhysical)
11144 continue;
11145 }
11146 else
11147 {
11148 if (!checkNonPhysical)
11149 continue;
11150 }
11151 }
11152
11153 refcount++;
11154 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart)
11155 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
11156 else
11157 list.Add(entity.UUID);
11158
11159 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11160 {
11161 if (entity is SceneObjectPart)
11162 list.Add(((SceneObjectPart)entity).LinkNum);
11163 else
11164 list.Add(0);
11165 }
11166
11167 list.Add(result.Pos);
11168
11169 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11170 list.Add(result.Normal);
11171 }
11172
11173 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED
11174
11175 return list;
11176 }
11003 11177
11004 #region Not Implemented 11178 #region Not Implemented
11005 // 11179 //
11006 // Listing the unimplemented lsl functions here, please move 11180 // Listing the unimplemented lsl functions here, please move
11007 // them from this region as they are completed 11181 // them from this region as they are completed
11008 // 11182 //
11009 public void llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11010 {
11011 m_host.AddScriptLPS(1);
11012 NotImplemented("llCastRay");
11013
11014 }
11015 11183
11016 public void llGetEnv(LSL_String name) 11184 public void llGetEnv(LSL_String name)
11017 { 11185 {
11018 m_host.AddScriptLPS(1); 11186 m_host.AddScriptLPS(1);
11019 NotImplemented("llGetEnv"); 11187 NotImplemented("llGetEnv");
11020
11021 } 11188 }
11022 11189
11023 public void llGetSPMaxMemory() 11190 public void llGetSPMaxMemory()
11024 { 11191 {
11025 m_host.AddScriptLPS(1); 11192 m_host.AddScriptLPS(1);
11026 NotImplemented("llGetSPMaxMemory"); 11193 NotImplemented("llGetSPMaxMemory");
11027
11028 } 11194 }
11029 11195
11030 public virtual LSL_Integer llGetUsedMemory() 11196 public virtual LSL_Integer llGetUsedMemory()
@@ -11034,18 +11200,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11034 return 0; 11200 return 0;
11035 } 11201 }
11036 11202
11037 public void llRegionSayTo( LSL_Key target, LSL_Integer channel, LSL_String msg ) 11203 public void llScriptProfiler(LSL_Integer flags)
11038 {
11039 m_host.AddScriptLPS(1);
11040 NotImplemented("llRegionSayTo");
11041
11042 }
11043
11044 public void llScriptProfiler( LSL_Integer flags )
11045 { 11204 {
11046 m_host.AddScriptLPS(1); 11205 m_host.AddScriptLPS(1);
11047 //NotImplemented("llScriptProfiler"); 11206 //NotImplemented("llScriptProfiler");
11048
11049 } 11207 }
11050 11208
11051 public void llSetSoundQueueing(int queue) 11209 public void llSetSoundQueueing(int queue)
@@ -11164,9 +11322,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11164 } 11322 }
11165 } 11323 }
11166 11324
11167 public static string GetLine(UUID assetID, int line, int maxLength) 11325 /// <summary>
11326 /// Get a notecard line.
11327 /// </summary>
11328 /// <param name="assetID"></param>
11329 /// <param name="line">Lines start at index 0</param>
11330 /// <returns></returns>
11331 public static string GetLine(UUID assetID, int lineNumber)
11168 { 11332 {
11169 if (line < 0) 11333 if (lineNumber < 0)
11170 return ""; 11334 return "";
11171 11335
11172 string data; 11336 string data;
@@ -11178,17 +11342,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11178 { 11342 {
11179 m_Notecards[assetID].lastRef = DateTime.Now; 11343 m_Notecards[assetID].lastRef = DateTime.Now;
11180 11344
11181 if (line >= m_Notecards[assetID].text.Length) 11345 if (lineNumber >= m_Notecards[assetID].text.Length)
11182 return "\n\n\n"; 11346 return "\n\n\n";
11183 11347
11184 data = m_Notecards[assetID].text[line]; 11348 data = m_Notecards[assetID].text[lineNumber];
11185 if (data.Length > maxLength)
11186 data = data.Substring(0, maxLength);
11187 11349
11188 return data; 11350 return data;
11189 } 11351 }
11190 } 11352 }
11191 11353
11354 /// <summary>
11355 /// Get a notecard line.
11356 /// </summary>
11357 /// <param name="assetID"></param>
11358 /// <param name="line">Lines start at index 0</param>
11359 /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para>
11360 /// <returns></returns>
11361 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
11362 {
11363 string line = GetLine(assetID, lineNumber);
11364
11365 if (line.Length > maxLength)
11366 line = line.Substring(0, maxLength);
11367
11368 return line;
11369 }
11370
11192 public static void CacheCheck() 11371 public static void CacheCheck()
11193 { 11372 {
11194 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 11373 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 645566e..80daf5b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -130,7 +130,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
130 int idx = 0; 130 int idx = 0;
131 while (idx < rules.Length) 131 while (idx < rules.Length)
132 { 132 {
133 uint rule = (uint)rules.GetLSLIntegerItem(idx); 133 LSL_Integer ruleInt = rules.GetLSLIntegerItem(idx);
134 uint rule = (uint)ruleInt;
134 LSL_List toadd = new LSL_List(); 135 LSL_List toadd = new LSL_List();
135 136
136 switch (rule) 137 switch (rule)
@@ -247,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
247 248
248 if (toadd.Length > 0) 249 if (toadd.Length > 0)
249 { 250 {
250 values.Add(rule); 251 values.Add(ruleInt);
251 values.Add(toadd.Data[0]); 252 values.Add(toadd.Data[0]);
252 } 253 }
253 idx++; 254 idx++;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 6d2efce..8f450f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -28,11 +28,16 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 33using System.Runtime.Remoting.Lifetime;
32using System.Text; 34using System.Text;
33using System.Net; 35using System.Net;
34using System.Threading; 36using System.Threading;
37using System.Xml;
38using log4net;
35using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
36using Nini.Config; 41using Nini.Config;
37using OpenSim; 42using OpenSim;
38using OpenSim.Framework; 43using OpenSim.Framework;
@@ -119,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
119 [Serializable] 124 [Serializable]
120 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi 125 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi
121 { 126 {
127// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
128
122 internal IScriptEngine m_ScriptEngine; 129 internal IScriptEngine m_ScriptEngine;
123 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there 130 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there
124 internal SceneObjectPart m_host; 131 internal SceneObjectPart m_host;
@@ -357,20 +364,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
357 System.Threading.Thread.Sleep(delay); 364 System.Threading.Thread.Sleep(delay);
358 } 365 }
359 366
360 //
361 // OpenSim functions
362 //
363 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 367 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
364 { 368 {
365 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight"); 369 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
366 return SetTerrainHeight(x, y, val); 370 return SetTerrainHeight(x, y, val);
367 } 371 }
372
368 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 373 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
369 { 374 {
370 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); 375 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
371 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 376 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
372 return SetTerrainHeight(x, y, val); 377 return SetTerrainHeight(x, y, val);
373 } 378 }
379
374 private LSL_Integer SetTerrainHeight(int x, int y, double val) 380 private LSL_Integer SetTerrainHeight(int x, int y, double val)
375 { 381 {
376 m_host.AddScriptLPS(1); 382 m_host.AddScriptLPS(1);
@@ -393,12 +399,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
393 CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight"); 399 CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight");
394 return GetTerrainHeight(x, y); 400 return GetTerrainHeight(x, y);
395 } 401 }
402
396 public LSL_Float osTerrainGetHeight(int x, int y) 403 public LSL_Float osTerrainGetHeight(int x, int y)
397 { 404 {
398 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight"); 405 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight");
399 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight"); 406 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight");
400 return GetTerrainHeight(x, y); 407 return GetTerrainHeight(x, y);
401 } 408 }
409
402 private LSL_Float GetTerrainHeight(int x, int y) 410 private LSL_Float GetTerrainHeight(int x, int y)
403 { 411 {
404 m_host.AddScriptLPS(1); 412 m_host.AddScriptLPS(1);
@@ -673,13 +681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
673 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater"); 681 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
674 682
675 m_host.AddScriptLPS(1); 683 m_host.AddScriptLPS(1);
676 if (m_host.ParentGroup != null) 684
677 { 685 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
678 if (m_host.ParentGroup.RootPart != null)
679 {
680 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
681 }
682 }
683 } 686 }
684 687
685 // Teleport functions 688 // Teleport functions
@@ -709,9 +712,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
709 == World.LandChannel.GetLandObject( 712 == World.LandChannel.GetLandObject(
710 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 713 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
711 { 714 {
712 World.RequestTeleportLocation(presence.ControllingClient, regionName, 715 // We will launch the teleport on a new thread so that when the script threads are terminated
713 new Vector3((float)position.x, (float)position.y, (float)position.z), 716 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
714 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation); 717 Util.FireAndForget(
718 o => World.RequestTeleportLocation(presence.ControllingClient, regionName,
719 new Vector3((float)position.x, (float)position.y, (float)position.z),
720 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
715 721
716 ScriptSleep(5000); 722 ScriptSleep(5000);
717 } 723 }
@@ -747,9 +753,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
747 == World.LandChannel.GetLandObject( 753 == World.LandChannel.GetLandObject(
748 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 754 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
749 { 755 {
750 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, 756 // We will launch the teleport on a new thread so that when the script threads are terminated
751 new Vector3((float)position.x, (float)position.y, (float)position.z), 757 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
752 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation); 758 Util.FireAndForget(
759 o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
760 new Vector3((float)position.x, (float)position.y, (float)position.z),
761 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
762
753 ScriptSleep(5000); 763 ScriptSleep(5000);
754 } 764 }
755 } 765 }
@@ -870,7 +880,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
870 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 880 ScenePresence target = (ScenePresence)World.Entities[avatarID];
871 if (target != null) 881 if (target != null)
872 { 882 {
873 UUID animID=UUID.Zero; 883 UUID animID = UUID.Zero;
874 m_host.TaskInventory.LockItemsForRead(true); 884 m_host.TaskInventory.LockItemsForRead(true);
875 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
876 { 886 {
@@ -1028,6 +1038,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1028 drawList += "PenColor " + color + "; "; 1038 drawList += "PenColor " + color + "; ";
1029 return drawList; 1039 return drawList;
1030 } 1040 }
1041
1031 // Deprecated 1042 // Deprecated
1032 public string osSetPenColour(string drawList, string colour) 1043 public string osSetPenColour(string drawList, string colour)
1033 { 1044 {
@@ -1189,11 +1200,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1189 OSSLDeprecated("osSunGetParam", "osGetSunParam"); 1200 OSSLDeprecated("osSunGetParam", "osGetSunParam");
1190 return GetSunParam(param); 1201 return GetSunParam(param);
1191 } 1202 }
1203
1192 public double osGetSunParam(string param) 1204 public double osGetSunParam(string param)
1193 { 1205 {
1194 CheckThreatLevel(ThreatLevel.None, "osGetSunParam"); 1206 CheckThreatLevel(ThreatLevel.None, "osGetSunParam");
1195 return GetSunParam(param); 1207 return GetSunParam(param);
1196 } 1208 }
1209
1197 private double GetSunParam(string param) 1210 private double GetSunParam(string param)
1198 { 1211 {
1199 m_host.AddScriptLPS(1); 1212 m_host.AddScriptLPS(1);
@@ -1215,11 +1228,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1215 OSSLDeprecated("osSunSetParam", "osSetSunParam"); 1228 OSSLDeprecated("osSunSetParam", "osSetSunParam");
1216 SetSunParam(param, value); 1229 SetSunParam(param, value);
1217 } 1230 }
1231
1218 public void osSetSunParam(string param, double value) 1232 public void osSetSunParam(string param, double value)
1219 { 1233 {
1220 CheckThreatLevel(ThreatLevel.None, "osSetSunParam"); 1234 CheckThreatLevel(ThreatLevel.None, "osSetSunParam");
1221 SetSunParam(param, value); 1235 SetSunParam(param, value);
1222 } 1236 }
1237
1223 private void SetSunParam(string param, double value) 1238 private void SetSunParam(string param, double value)
1224 { 1239 {
1225 m_host.AddScriptLPS(1); 1240 m_host.AddScriptLPS(1);
@@ -1229,10 +1244,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1229 { 1244 {
1230 module.SetSunParameter(param, value); 1245 module.SetSunParameter(param, value);
1231 } 1246 }
1232
1233 } 1247 }
1234 1248
1235
1236 public string osWindActiveModelPluginName() 1249 public string osWindActiveModelPluginName()
1237 { 1250 {
1238 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName"); 1251 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName");
@@ -1311,12 +1324,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1311 OSSLDeprecated(functionName, "osSetParcelDetails"); 1324 OSSLDeprecated(functionName, "osSetParcelDetails");
1312 SetParcelDetails(pos, rules, functionName); 1325 SetParcelDetails(pos, rules, functionName);
1313 } 1326 }
1327
1314 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules) 1328 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules)
1315 { 1329 {
1316 const string functionName = "osSetParcelDetails"; 1330 const string functionName = "osSetParcelDetails";
1317 CheckThreatLevel(ThreatLevel.High, functionName); 1331 CheckThreatLevel(ThreatLevel.High, functionName);
1318 SetParcelDetails(pos, rules, functionName); 1332 SetParcelDetails(pos, rules, functionName);
1319 } 1333 }
1334
1320 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) 1335 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName)
1321 { 1336 {
1322 m_host.AddScriptLPS(1); 1337 m_host.AddScriptLPS(1);
@@ -1436,8 +1451,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1436 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); 1451 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID);
1437 else 1452 else
1438 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); 1453 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
1439
1440
1441 } 1454 }
1442 1455
1443 public string osGetScriptEngineName() 1456 public string osGetScriptEngineName()
@@ -1690,8 +1703,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1690 return jsondata; 1703 return jsondata;
1691 } 1704 }
1692 1705
1693 // send a message to to object identified by the given UUID, a script in the object must implement the dataserver function 1706 /// <summary>
1694 // the dataserver function is passed the ID of the calling function and a string message 1707 /// Send a message to to object identified by the given UUID
1708 /// </summary>
1709 /// <remarks>
1710 /// A script in the object must implement the dataserver function
1711 /// the dataserver function is passed the ID of the calling function and a string message
1712 /// </remarks>
1713 /// <param name="objectUUID"></param>
1714 /// <param name="message"></param>
1695 public void osMessageObject(LSL_Key objectUUID, string message) 1715 public void osMessageObject(LSL_Key objectUUID, string message)
1696 { 1716 {
1697 CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); 1717 CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
@@ -1706,34 +1726,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1706 "dataserver", resobj, new DetectParams[0])); 1726 "dataserver", resobj, new DetectParams[0]));
1707 } 1727 }
1708 1728
1709 1729 /// <summary>
1710 // This needs ThreatLevel high. It is an excellent griefer tool, 1730 /// Write a notecard directly to the prim's inventory.
1711 // In a loop, it can cause asset bloat and DOS levels of asset 1731 /// </summary>
1712 // writes. 1732 /// <remarks>
1713 // 1733 /// This needs ThreatLevel high. It is an excellent griefer tool,
1734 /// In a loop, it can cause asset bloat and DOS levels of asset
1735 /// writes.
1736 /// </remarks>
1737 /// <param name="notecardName">The name of the notecard to write.</param>
1738 /// <param name="contents">The contents of the notecard.</param>
1714 public void osMakeNotecard(string notecardName, LSL_Types.list contents) 1739 public void osMakeNotecard(string notecardName, LSL_Types.list contents)
1715 { 1740 {
1716 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard"); 1741 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
1717 m_host.AddScriptLPS(1); 1742 m_host.AddScriptLPS(1);
1718 1743
1719 // Create new asset 1744 StringBuilder notecardData = new StringBuilder();
1720 AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString());
1721 asset.Description = "Script Generated Notecard";
1722 string notecardData = String.Empty;
1723 1745
1724 for (int i = 0; i < contents.Length; i++) { 1746 for (int i = 0; i < contents.Length; i++)
1725 notecardData += contents.GetLSLStringItem(i) + "\n"; 1747 notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n"));
1726 } 1748
1749 SaveNotecard(notecardName, "Script generated notecard", notecardData.ToString(), false);
1750 }
1727 1751
1728 int textLength = notecardData.Length; 1752 /// <summary>
1729 notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " 1753 /// Save a notecard to prim inventory.
1730 + textLength.ToString() + "\n" + notecardData + "}\n"; 1754 /// </summary>
1755 /// <param name="name"></param>
1756 /// <param name="description">Description of notecard</param>
1757 /// <param name="notecardData"></param>
1758 /// <param name="forceSameName">
1759 /// If true, then if an item exists with the same name, it is replaced.
1760 /// If false, then a new item is created witha slightly different name (e.g. name 1)
1761 /// </param>
1762 /// <returns>Prim inventory item created.</returns>
1763 protected TaskInventoryItem SaveNotecard(string name, string description, string data, bool forceSameName)
1764 {
1765 // Create new asset
1766 AssetBase asset = new AssetBase(UUID.Random(), name, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString());
1767 asset.Description = description;
1731 1768
1732 asset.Data = Util.UTF8.GetBytes(notecardData); 1769 int textLength = data.Length;
1770 data
1771 = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
1772 + textLength.ToString() + "\n" + data + "}\n";
1773
1774 asset.Data = Util.UTF8.GetBytes(data);
1733 World.AssetService.Store(asset); 1775 World.AssetService.Store(asset);
1734 1776
1735 // Create Task Entry 1777 // Create Task Entry
1736 TaskInventoryItem taskItem=new TaskInventoryItem(); 1778 TaskInventoryItem taskItem = new TaskInventoryItem();
1737 1779
1738 taskItem.ResetIDs(m_host.UUID); 1780 taskItem.ResetIDs(m_host.UUID);
1739 taskItem.ParentID = m_host.UUID; 1781 taskItem.ParentID = m_host.UUID;
@@ -1755,29 +1797,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1755 taskItem.PermsMask = 0; 1797 taskItem.PermsMask = 0;
1756 taskItem.AssetID = asset.FullID; 1798 taskItem.AssetID = asset.FullID;
1757 1799
1758 m_host.Inventory.AddInventoryItem(taskItem, false); 1800 if (forceSameName)
1801 m_host.Inventory.AddInventoryItemExclusive(taskItem, false);
1802 else
1803 m_host.Inventory.AddInventoryItem(taskItem, false);
1804
1805 return taskItem;
1759 } 1806 }
1760 1807
1808 /// <summary>
1809 /// Load the notecard data found at the given prim inventory item name or asset uuid.
1810 /// </summary>
1811 /// <param name="notecardNameOrUuid"></param>
1812 /// <returns>The text loaded. Null if no notecard was found.</returns>
1813 protected string LoadNotecard(string notecardNameOrUuid)
1814 {
1815 UUID assetID = CacheNotecard(notecardNameOrUuid);
1816 StringBuilder notecardData = new StringBuilder();
1761 1817
1762 /*Instead of using the LSL Dataserver event to pull notecard data, 1818 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1763 this will simply read the requested line and return its data as a string. 1819 {
1820 string line = NotecardCache.GetLine(assetID, count) + "\n";
1764 1821
1765 Warning - due to the synchronous method this function uses to fetch assets, its use 1822// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
1766 may be dangerous and unreliable while running in grid mode.
1767 */
1768 public string osGetNotecardLine(string name, int line)
1769 {
1770 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1771 m_host.AddScriptLPS(1);
1772 1823
1824 notecardData.Append(line);
1825 }
1826
1827 return notecardData.ToString();
1828 }
1829
1830 /// <summary>
1831 /// Cache a notecard's contents.
1832 /// </summary>
1833 /// <param name="notecardNameOrUuid"></param>
1834 /// <returns>
1835 /// The asset id of the notecard, which is used for retrieving the cached data.
1836 /// UUID.Zero if no asset could be found.
1837 /// </returns>
1838 protected UUID CacheNotecard(string notecardNameOrUuid)
1839 {
1773 UUID assetID = UUID.Zero; 1840 UUID assetID = UUID.Zero;
1774 1841
1775 if (!UUID.TryParse(name, out assetID)) 1842 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1776 { 1843 {
1777 m_host.TaskInventory.LockItemsForRead(true); 1844 m_host.TaskInventory.LockItemsForRead(true);
1778 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1779 { 1846 {
1780 if (item.Type == 7 && item.Name == name) 1847 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1781 { 1848 {
1782 assetID = item.AssetID; 1849 assetID = item.AssetID;
1783 } 1850 }
@@ -1786,118 +1853,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 } 1853 }
1787 1854
1788 if (assetID == UUID.Zero) 1855 if (assetID == UUID.Zero)
1789 { 1856 return UUID.Zero;
1790 OSSLShoutError("Notecard '" + name + "' could not be found.");
1791 return "ERROR!";
1792 }
1793 1857
1794 if (!NotecardCache.IsCached(assetID)) 1858 if (!NotecardCache.IsCached(assetID))
1795 { 1859 {
1796 AssetBase a = World.AssetService.Get(assetID.ToString()); 1860 AssetBase a = World.AssetService.Get(assetID.ToString());
1797 if (a != null)
1798 {
1799 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1800 string data = enc.GetString(a.Data);
1801 NotecardCache.Cache(assetID, data);
1802 }
1803 else
1804 {
1805 OSSLShoutError("Notecard '" + name + "' could not be found.");
1806 return "ERROR!";
1807 }
1808 };
1809 1861
1810 return NotecardCache.GetLine(assetID, line, 255); 1862 if (a == null)
1863 return UUID.Zero;
1811 1864
1865 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1866 string data = enc.GetString(a.Data);
1867 NotecardCache.Cache(assetID, data);
1868 };
1812 1869
1870 return assetID;
1813 } 1871 }
1814 1872
1815 /*Instead of using the LSL Dataserver event to pull notecard data line by line, 1873 /// <summary>
1816 this will simply read the entire notecard and return its data as a string. 1874 /// Directly get an entire notecard at once.
1875 /// </summary>
1876 /// <remarks>
1877 /// Instead of using the LSL Dataserver event to pull notecard data
1878 /// this will simply read the entire notecard and return its data as a string.
1879 ///
1880 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1881 /// may be dangerous and unreliable while running in grid mode.
1882 /// </remarks>
1883 /// <param name="name">Name of the notecard or its asset id</param>
1884 /// <param name="line">The line number to read. The first line is line 0</param>
1885 /// <returns>Notecard line</returns>
1886 public string osGetNotecardLine(string name, int line)
1887 {
1888 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1889 m_host.AddScriptLPS(1);
1817 1890
1818 Warning - due to the synchronous method this function uses to fetch assets, its use 1891 UUID assetID = CacheNotecard(name);
1819 may be dangerous and unreliable while running in grid mode.
1820 */
1821 1892
1893 if (assetID == UUID.Zero)
1894 {
1895 OSSLShoutError("Notecard '" + name + "' could not be found.");
1896 return "ERROR!";
1897 }
1898
1899 return NotecardCache.GetLine(assetID, line);
1900 }
1901
1902 /// <summary>
1903 /// Get an entire notecard at once.
1904 /// </summary>
1905 /// <remarks>
1906 /// Instead of using the LSL Dataserver event to pull notecard data line by line,
1907 /// this will simply read the entire notecard and return its data as a string.
1908 ///
1909 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1910 /// may be dangerous and unreliable while running in grid mode.
1911 /// </remarks>
1912 /// <param name="name">Name of the notecard or its asset id</param>
1913 /// <returns>Notecard text</returns>
1822 public string osGetNotecard(string name) 1914 public string osGetNotecard(string name)
1823 { 1915 {
1824 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); 1916 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard");
1825 m_host.AddScriptLPS(1); 1917 m_host.AddScriptLPS(1);
1826 1918
1827 UUID assetID = UUID.Zero; 1919 string text = LoadNotecard(name);
1828 string NotecardData = "";
1829 1920
1830 if (!UUID.TryParse(name, out assetID)) 1921 if (text == null)
1831 {
1832 m_host.TaskInventory.LockItemsForRead(true);
1833 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1834 {
1835 if (item.Type == 7 && item.Name == name)
1836 {
1837 assetID = item.AssetID;
1838 }
1839 }
1840 m_host.TaskInventory.LockItemsForRead(false);
1841 }
1842
1843 if (assetID == UUID.Zero)
1844 { 1922 {
1845 OSSLShoutError("Notecard '" + name + "' could not be found."); 1923 OSSLShoutError("Notecard '" + name + "' could not be found.");
1846 return "ERROR!"; 1924 return "ERROR!";
1847 } 1925 }
1848 1926 else
1849 if (!NotecardCache.IsCached(assetID))
1850 {
1851 AssetBase a = World.AssetService.Get(assetID.ToString());
1852 if (a != null)
1853 {
1854 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1855 string data = enc.GetString(a.Data);
1856 NotecardCache.Cache(assetID, data);
1857 }
1858 else
1859 {
1860 OSSLShoutError("Notecard '" + name + "' could not be found.");
1861 return "ERROR!";
1862 }
1863 };
1864
1865 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1866 { 1927 {
1867 NotecardData += NotecardCache.GetLine(assetID, count, 255) + "\n"; 1928 return text;
1868 } 1929 }
1869
1870 return NotecardData;
1871
1872
1873 } 1930 }
1874 1931
1875 /*Instead of using the LSL Dataserver event to pull notecard data, 1932 /// <summary>
1876 this will simply read the number of note card lines and return this data as an integer. 1933 /// Get the number of lines in the given notecard.
1877 1934 /// </summary>
1878 Warning - due to the synchronous method this function uses to fetch assets, its use 1935 /// <remarks>
1879 may be dangerous and unreliable while running in grid mode. 1936 /// Instead of using the LSL Dataserver event to pull notecard data,
1880 */ 1937 /// this will simply read the number of note card lines and return this data as an integer.
1881 1938 ///
1939 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1940 /// may be dangerous and unreliable while running in grid mode.
1941 /// </remarks>
1942 /// <param name="name">Name of the notecard or its asset id</param>
1943 /// <returns></returns>
1882 public int osGetNumberOfNotecardLines(string name) 1944 public int osGetNumberOfNotecardLines(string name)
1883 { 1945 {
1884 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); 1946 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines");
1885 m_host.AddScriptLPS(1); 1947 m_host.AddScriptLPS(1);
1886 1948
1887 UUID assetID = UUID.Zero; 1949 UUID assetID = CacheNotecard(name);
1888
1889 if (!UUID.TryParse(name, out assetID))
1890 {
1891 m_host.TaskInventory.LockItemsForRead(true);
1892 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1893 {
1894 if (item.Type == 7 && item.Name == name)
1895 {
1896 assetID = item.AssetID;
1897 }
1898 }
1899 m_host.TaskInventory.LockItemsForRead(false);
1900 }
1901 1950
1902 if (assetID == UUID.Zero) 1951 if (assetID == UUID.Zero)
1903 { 1952 {
@@ -1905,25 +1954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1905 return -1; 1954 return -1;
1906 } 1955 }
1907 1956
1908 if (!NotecardCache.IsCached(assetID))
1909 {
1910 AssetBase a = World.AssetService.Get(assetID.ToString());
1911 if (a != null)
1912 {
1913 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1914 string data = enc.GetString(a.Data);
1915 NotecardCache.Cache(assetID, data);
1916 }
1917 else
1918 {
1919 OSSLShoutError("Notecard '" + name + "' could not be found.");
1920 return -1;
1921 }
1922 };
1923
1924 return NotecardCache.GetLines(assetID); 1957 return NotecardCache.GetLines(assetID);
1925
1926
1927 } 1958 }
1928 1959
1929 public string osAvatarName2Key(string firstname, string lastname) 1960 public string osAvatarName2Key(string firstname, string lastname)
@@ -1962,15 +1993,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1962 { 1993 {
1963 return ""; 1994 return "";
1964 } 1995 }
1965
1966 } 1996 }
1967 1997
1998 /// <summary>
1999 /// Get the nickname of this grid, as set in the [GridInfo] config section.
2000 /// </summary>
2001 /// <remarks>
1968 /// Threat level is Moderate because intentional abuse, for instance 2002 /// Threat level is Moderate because intentional abuse, for instance
1969 /// scripts that are written to be malicious only on one grid, 2003 /// scripts that are written to be malicious only on one grid,
1970 /// for instance in a HG scenario, are a distinct possibility. 2004 /// for instance in a HG scenario, are a distinct possibility.
1971 /// 2005 /// </remarks>
1972 /// Use value from the config file and return it. 2006 /// <returns></returns>
1973 ///
1974 public string osGetGridNick() 2007 public string osGetGridNick()
1975 { 2008 {
1976 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); 2009 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
@@ -2037,7 +2070,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2037 // Find matches beginning at start position 2070 // Find matches beginning at start position
2038 Regex matcher = new Regex(pattern); 2071 Regex matcher = new Regex(pattern);
2039 Match match = matcher.Match(src, start); 2072 Match match = matcher.Match(src, start);
2040 if (match.Success) 2073 while (match.Success)
2041 { 2074 {
2042 foreach (System.Text.RegularExpressions.Group g in match.Groups) 2075 foreach (System.Text.RegularExpressions.Group g in match.Groups)
2043 { 2076 {
@@ -2047,6 +2080,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2047 result.Add(new LSL_Integer(g.Index)); 2080 result.Add(new LSL_Integer(g.Index));
2048 } 2081 }
2049 } 2082 }
2083
2084 match = match.NextMatch();
2050 } 2085 }
2051 2086
2052 return result; 2087 return result;
@@ -2076,12 +2111,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2076 return World.RegionInfo.RegionSettings.LoadedCreationID; 2111 return World.RegionInfo.RegionSettings.LoadedCreationID;
2077 } 2112 }
2078 2113
2079 // Threat level is 'Low' because certain users could possibly be tricked into 2114 /// <summary>
2080 // dropping an unverified script into one of their own objects, which could 2115 /// Get the primitive parameters of a linked prim.
2081 // then gather the physical construction details of the object and transmit it 2116 /// </summary>
2082 // to an unscrupulous third party, thus permitting unauthorized duplication of 2117 /// <remarks>
2083 // the object's form. 2118 /// Threat level is 'Low' because certain users could possibly be tricked into
2084 // 2119 /// dropping an unverified script into one of their own objects, which could
2120 /// then gather the physical construction details of the object and transmit it
2121 /// to an unscrupulous third party, thus permitting unauthorized duplication of
2122 /// the object's form.
2123 /// </remarks>
2124 /// <param name="linknumber"></param>
2125 /// <param name="rules"></param>
2126 /// <returns></returns>
2085 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 2127 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
2086 { 2128 {
2087 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2129 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
@@ -2096,25 +2138,121 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2096 return retVal; 2138 return retVal;
2097 } 2139 }
2098 2140
2099 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) 2141 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2100 { 2142 {
2101 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2143 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2102 //QueueUserWorkItem
2103 2144
2104 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2145 INPCModule module = World.RequestModuleInterface<INPCModule>();
2105 if (module != null) 2146 if (module != null)
2106 { 2147 {
2148 AvatarAppearance appearance = null;
2149
2150 UUID id;
2151 if (UUID.TryParse(notecard, out id))
2152 {
2153 ScenePresence clonePresence = World.GetScenePresence(id);
2154 if (clonePresence != null)
2155 appearance = clonePresence.Appearance;
2156 }
2157
2158 if (appearance == null)
2159 {
2160 string appearanceSerialized = LoadNotecard(notecard);
2161
2162 if (appearanceSerialized != null)
2163 {
2164 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2165 appearance = new AvatarAppearance();
2166 appearance.Unpack(appearanceOsd);
2167 }
2168 }
2169
2170 if (appearance == null)
2171 return new LSL_Key(UUID.Zero.ToString());
2172
2107 UUID x = module.CreateNPC(firstname, 2173 UUID x = module.CreateNPC(firstname,
2108 lastname, 2174 lastname,
2109 new Vector3((float) position.x, (float) position.y, (float) position.z), 2175 new Vector3((float) position.x, (float) position.y, (float) position.z),
2110 World, 2176 World,appearance);
2111 new UUID(cloneFrom));
2112 2177
2113 return new LSL_Key(x.ToString()); 2178 return new LSL_Key(x.ToString());
2114 } 2179 }
2180
2181 return new LSL_Key(UUID.Zero.ToString());
2182 }
2183
2184 /// <summary>
2185 /// Save the current appearance of the NPC permanently to the named notecard.
2186 /// </summary>
2187 /// <param name="avatar"></param>
2188 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2189 /// <returns>The asset ID of the notecard saved.</returns>
2190 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2191 {
2192 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2193
2194 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2195
2196 if (npcModule != null)
2197 {
2198 UUID npcId;
2199 if (!UUID.TryParse(npc.m_string, out npcId))
2200 return new LSL_Key(UUID.Zero.ToString());
2201
2202 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2203 return new LSL_Key(UUID.Zero.ToString());
2204
2205 return SaveAppearanceToNotecard(npcId, notecard);
2206 }
2207
2115 return new LSL_Key(UUID.Zero.ToString()); 2208 return new LSL_Key(UUID.Zero.ToString());
2116 } 2209 }
2117 2210
2211 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2212 {
2213 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2214
2215 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2216
2217 if (npcModule != null)
2218 {
2219 UUID npcId;
2220 if (!UUID.TryParse(npc.m_string, out npcId))
2221 return;
2222
2223 string appearanceSerialized = LoadNotecard(notecard);
2224 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2225// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
2226// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized);
2227// Console.WriteLine("a.Type {0}, a.ToString() {1}", a.Type, a);
2228 AvatarAppearance appearance = new AvatarAppearance();
2229 appearance.Unpack(appearanceOsd);
2230
2231 npcModule.SetNPCAppearance(npcId, appearance, m_host.ParentGroup.Scene);
2232 }
2233 }
2234
2235 public LSL_Vector osNpcGetPos(LSL_Key npc)
2236 {
2237 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2238
2239 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2240 if (npcModule != null)
2241 {
2242 UUID npcId;
2243 if (!UUID.TryParse(npc.m_string, out npcId))
2244 return new LSL_Vector(0, 0, 0);
2245
2246 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2247 return new LSL_Vector(0, 0, 0);
2248
2249 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
2250 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2251 }
2252
2253 return new LSL_Vector(0, 0, 0);
2254 }
2255
2118 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2256 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
2119 { 2257 {
2120 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2258 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
@@ -2122,11 +2260,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2122 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2260 INPCModule module = World.RequestModuleInterface<INPCModule>();
2123 if (module != null) 2261 if (module != null)
2124 { 2262 {
2263 UUID npcId;
2264 if (!UUID.TryParse(npc.m_string, out npcId))
2265 return;
2266
2125 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2267 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2126 module.Autopilot(new UUID(npc.m_string), World, pos); 2268 module.MoveToTarget(npcId, World, pos, false, true);
2127 } 2269 }
2128 } 2270 }
2129 2271
2272 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2273 {
2274 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2275
2276 INPCModule module = World.RequestModuleInterface<INPCModule>();
2277 if (module != null)
2278 {
2279 UUID npcId;
2280 if (!UUID.TryParse(npc.m_string, out npcId))
2281 return;
2282
2283 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2284 module.MoveToTarget(
2285 new UUID(npc.m_string),
2286 World,
2287 pos,
2288 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2289 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0);
2290 }
2291 }
2292
2293 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2294 {
2295 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2296
2297 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2298 if (npcModule != null)
2299 {
2300 UUID npcId;
2301 if (!UUID.TryParse(npc.m_string, out npcId))
2302 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2303
2304 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2305 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2306
2307 ScenePresence sp = World.GetScenePresence(npcId);
2308 Quaternion rot = sp.Rotation;
2309
2310 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2311 }
2312
2313 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2314 }
2315
2316 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2317 {
2318 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2319
2320 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2321 if (npcModule != null)
2322 {
2323 UUID npcId;
2324 if (!UUID.TryParse(npc.m_string, out npcId))
2325 return;
2326
2327 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2328 return;
2329
2330 ScenePresence sp = World.GetScenePresence(npcId);
2331 sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
2332 }
2333 }
2334
2335 public void osNpcStopMoveToTarget(LSL_Key npc)
2336 {
2337 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo");
2338
2339 INPCModule module = World.RequestModuleInterface<INPCModule>();
2340 if (module != null)
2341 module.StopMoveToTarget(new UUID(npc.m_string), World);
2342 }
2343
2130 public void osNpcSay(LSL_Key npc, string message) 2344 public void osNpcSay(LSL_Key npc, string message)
2131 { 2345 {
2132 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2346 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
@@ -2148,6 +2362,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2148 module.DeleteNPC(new UUID(npc.m_string), World); 2362 module.DeleteNPC(new UUID(npc.m_string), World);
2149 } 2363 }
2150 } 2364 }
2365
2366 /// <summary>
2367 /// Save the current appearance of the script owner permanently to the named notecard.
2368 /// </summary>
2369 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2370 /// <returns>The asset ID of the notecard saved.</returns>
2371 public LSL_Key osOwnerSaveAppearance(string notecard)
2372 {
2373 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2374
2375 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2376 }
2377
2378 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2379 {
2380 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2381
2382 return SaveAppearanceToNotecard(avatarId, notecard);
2383 }
2384
2385 protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecard)
2386 {
2387 IAvatarFactory appearanceModule = World.RequestModuleInterface<IAvatarFactory>();
2388
2389 if (appearanceModule != null)
2390 {
2391 appearanceModule.SaveBakedTextures(sp.UUID);
2392 OSDMap appearancePacked = sp.Appearance.Pack();
2393
2394 TaskInventoryItem item
2395 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
2396
2397 return new LSL_Key(item.AssetID.ToString());
2398 }
2399 else
2400 {
2401 return new LSL_Key(UUID.Zero.ToString());
2402 }
2403 }
2404
2405 protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecard)
2406 {
2407 ScenePresence sp = World.GetScenePresence(avatarId);
2408
2409 if (sp == null || sp.IsChildAgent)
2410 return new LSL_Key(UUID.Zero.ToString());
2411
2412 return SaveAppearanceToNotecard(sp, notecard);
2413 }
2414
2415 protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecard)
2416 {
2417 UUID avatarId;
2418 if (!UUID.TryParse(rawAvatarId, out avatarId))
2419 return new LSL_Key(UUID.Zero.ToString());
2420
2421 return SaveAppearanceToNotecard(avatarId, notecard);
2422 }
2151 2423
2152 /// <summary> 2424 /// <summary>
2153 /// Get current region's map texture UUID 2425 /// Get current region's map texture UUID
@@ -2357,10 +2629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2357 obj.Shape.ProjectionFocus = (float)focus; 2629 obj.Shape.ProjectionFocus = (float)focus;
2358 obj.Shape.ProjectionAmbiance = (float)amb; 2630 obj.Shape.ProjectionAmbiance = (float)amb;
2359 2631
2360
2361 obj.ParentGroup.HasGroupChanged = true; 2632 obj.ParentGroup.HasGroupChanged = true;
2362 obj.ScheduleFullUpdate(); 2633 obj.ScheduleFullUpdate();
2363
2364 } 2634 }
2365 2635
2366 /// <summary> 2636 /// <summary>
@@ -2385,6 +2655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2385 } 2655 }
2386 } 2656 }
2387 }); 2657 });
2658
2388 return result; 2659 return result;
2389 } 2660 }
2390 2661
@@ -2404,4 +2675,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2404 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2675 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2405 } 2676 }
2406 } 2677 }
2407} 2678} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index d695a0c..6de0773 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -304,12 +304,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
304 304
305// Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation! 306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
307 if (SensePoint.ParentGroup.RootPart.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
308 { 308 {
309 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
310 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
311 // in mouselook. 311 // in mouselook.
312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition; 313 fromRegionPos = avatar.AbsolutePosition;
314 q = avatar.Rotation; 314 q = avatar.Rotation;
315 } 315 }
@@ -354,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
354 objtype = 0; 354 objtype = 0;
355 355
356 part = ((SceneObjectGroup)ent).RootPart; 356 part = ((SceneObjectGroup)ent).RootPart;
357 if (part.AttachmentPoint != 0) // Attached so ignore 357 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
358 continue; 358 continue;
359 359
360 if (part.Inventory.ContainsScripts()) 360 if (part.Inventory.ContainsScripts())
@@ -425,13 +425,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
425 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
426 426
427 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.RootPart.IsAttachment) 428 if (SensePoint.ParentGroup.IsAttachment)
429 { 429 {
430 // In attachments, the sensor cone always orients with the 430 // In attachments, the sensor cone always orients with the
431 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
432 // in mouselook. 432 // in mouselook.
433 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
435 fromRegionPos = avatar.AbsolutePosition; 434 fromRegionPos = avatar.AbsolutePosition;
436 q = avatar.Rotation; 435 q = avatar.Rotation;
437 } 436 }
@@ -439,7 +438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
439 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
440 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
441 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
442 bool attached = (SensePoint.AttachmentPoint != 0); 441 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
443 Vector3 toRegionPos; 442 Vector3 toRegionPos;
444 double dis; 443 double dis;
445 444
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index ce13d6b..7c388fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -60,6 +60,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
60 LSL_String llBase64ToString(string str); 60 LSL_String llBase64ToString(string str);
61 void llBreakAllLinks(); 61 void llBreakAllLinks();
62 void llBreakLink(int linknum); 62 void llBreakLink(int linknum);
63 LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options);
63 LSL_Integer llCeil(double f); 64 LSL_Integer llCeil(double f);
64 void llClearCameraParams(); 65 void llClearCameraParams();
65 LSL_Integer llClearPrimMedia(LSL_Integer face); 66 LSL_Integer llClearPrimMedia(LSL_Integer face);
@@ -271,6 +272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
271 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local); 272 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local);
272 void llRefreshPrimURL(); 273 void llRefreshPrimURL();
273 void llRegionSay(int channelID, string text); 274 void llRegionSay(int channelID, string text);
275 void llRegionSayTo(string target, int channelID, string text);
274 void llReleaseCamera(string avatar); 276 void llReleaseCamera(string avatar);
275 void llReleaseControls(); 277 void llReleaseControls();
276 void llReleaseURL(string url); 278 void llReleaseURL(string url);
@@ -405,7 +407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_String llXorBase64StringsCorrect(string str1, string str2); 407 LSL_String llXorBase64StringsCorrect(string str1, string str2);
406 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 408 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
407 409
408 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
409 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
410 } 412 }
411} 413}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 5a809e6..5ddba60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -168,12 +168,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
168 168
169 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 169 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
170 170
171 171 key osNpcCreate(string user, string name, vector position, string notecard);
172 key osNpcCreate(string user, string name, vector position, key cloneFrom); 172 LSL_Key osNpcSaveAppearance(key npc, string notecard);
173 void osNpcLoadAppearance(key npc, string notecard);
174 vector osNpcGetPos(key npc);
173 void osNpcMoveTo(key npc, vector position); 175 void osNpcMoveTo(key npc, vector position);
176 void osNpcMoveToTarget(key npc, vector target, int options);
177 rotation osNpcGetRot(key npc);
178 void osNpcSetRot(LSL_Key npc, rotation rot);
179 void osNpcStopMoveToTarget(LSL_Key npc);
174 void osNpcSay(key npc, string message); 180 void osNpcSay(key npc, string message);
175 void osNpcRemove(key npc); 181 void osNpcRemove(key npc);
176 182
183 LSL_Key osOwnerSaveAppearance(string notecard);
184 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
185
177 key osGetMapTexture(); 186 key osGetMapTexture();
178 key osGetRegionMapTexture(string regionName); 187 key osGetRegionMapTexture(string regionName);
179 LSL_List osGetRegionStats(); 188 LSL_List osGetRegionStats();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 5f94ff5..59eaccb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -594,7 +594,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
594 public const int STATS_ACTIVE_SCRIPTS = 19; 594 public const int STATS_ACTIVE_SCRIPTS = 19;
595 public const int STATS_SCRIPT_LPS = 20; 595 public const int STATS_SCRIPT_LPS = 20;
596 596
597 // Constants for osNpc* functions
598 public const int OS_NPC_FLY = 0;
599 public const int OS_NPC_NO_FLY = 1;
600 public const int OS_NPC_LAND_AT_TARGET = 2;
601
597 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; 602 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
598 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; 603 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
604
605 public static readonly LSLInteger RC_REJECT_TYPES = 2;
606 public static readonly LSLInteger RC_DATA_FLAGS = 4;
607 public static readonly LSLInteger RC_MAX_HITS = 8;
608 public static readonly LSLInteger RC_DETECT_PHANTOM = 16;
609
610 public static readonly LSLInteger RC_REJECT_AGENTS = 2;
611 public static readonly LSLInteger RC_REJECT_PHYSICAL = 4;
612 public static readonly LSLInteger RC_REJECT_NONPHYSICAL = 8;
613 public static readonly LSLInteger RC_REJECT_LAND = 16;
614
615 public static readonly LSLInteger RC_GET_NORMAL = 2;
616 public static readonly LSLInteger RC_GET_ROOT_KEY = 4;
617 public static readonly LSLInteger RC_GET_LINK_NUM = 8;
618
619 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 1;
599 } 620 }
600} 621}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 7d7e54e..ca54862 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1206,6 +1206,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1206 m_LSL_Functions.llRegionSay(channelID, text); 1206 m_LSL_Functions.llRegionSay(channelID, text);
1207 } 1207 }
1208 1208
1209 public void llRegionSayTo(string key, int channelID, string text)
1210 {
1211 m_LSL_Functions.llRegionSayTo(key, channelID, text);
1212 }
1213
1209 public void llReleaseCamera(string avatar) 1214 public void llReleaseCamera(string avatar)
1210 { 1215 {
1211 m_LSL_Functions.llReleaseCamera(avatar); 1216 m_LSL_Functions.llReleaseCamera(avatar);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 7c59098..bbc8cc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -483,11 +483,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
483 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); 483 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
484 } 484 }
485 485
486 public key osNpcSaveAppearance(key npc, string notecard)
487 {
488 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
489 }
490
491 public void osNpcLoadAppearance(key npc, string notecard)
492 {
493 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard);
494 }
495
496 public vector osNpcGetPos(LSL_Key npc)
497 {
498 return m_OSSL_Functions.osNpcGetPos(npc);
499 }
500
486 public void osNpcMoveTo(key npc, vector position) 501 public void osNpcMoveTo(key npc, vector position)
487 { 502 {
488 m_OSSL_Functions.osNpcMoveTo(npc, position); 503 m_OSSL_Functions.osNpcMoveTo(npc, position);
489 } 504 }
490 505
506 public void osNpcMoveToTarget(key npc, vector target, int options)
507 {
508 m_OSSL_Functions.osNpcMoveToTarget(npc, target, options);
509 }
510
511 public rotation osNpcGetRot(key npc)
512 {
513 return m_OSSL_Functions.osNpcGetRot(npc);
514 }
515
516 public void osNpcSetRot(key npc, rotation rot)
517 {
518 m_OSSL_Functions.osNpcSetRot(npc, rot);
519 }
520
521 public void osNpcStopMoveToTarget(LSL_Key npc)
522 {
523 m_OSSL_Functions.osNpcStopMoveToTarget(npc);
524 }
525
491 public void osNpcSay(key npc, string message) 526 public void osNpcSay(key npc, string message)
492 { 527 {
493 m_OSSL_Functions.osNpcSay(npc, message); 528 m_OSSL_Functions.osNpcSay(npc, message);
@@ -498,6 +533,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
498 m_OSSL_Functions.osNpcRemove(npc); 533 m_OSSL_Functions.osNpcRemove(npc);
499 } 534 }
500 535
536 public LSL_Key osOwnerSaveAppearance(string notecard)
537 {
538 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
539 }
540
541 public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecard)
542 {
543 return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecard);
544 }
545
501 public OSSLPrim Prim; 546 public OSSLPrim Prim;
502 547
503 [Serializable] 548 [Serializable]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index e9edf6c..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
205 return; 205 return;
206 } 206 }
207 207
208 part=part.ParentGroup.RootPart; // We detect objects only 208 part = part.ParentGroup.RootPart; // We detect objects only
209 209
210 LinkNum = 0; // Not relevant 210 LinkNum = 0; // Not relevant
211 211
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 9548253..cf25189 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -234,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
234 m_MaxScriptQueue = maxScriptQueue; 234 m_MaxScriptQueue = maxScriptQueue;
235 m_stateSource = stateSource; 235 m_stateSource = stateSource;
236 m_postOnRez = postOnRez; 236 m_postOnRez = postOnRez;
237 m_AttachedAvatar = part.AttachedAvatar; 237 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
238 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; 238 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
239 239
240 if (part != null) 240 if (part != null)
@@ -772,13 +772,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
772 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 772 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
773 { 773 {
774 m_InSelfDelete = true; 774 m_InSelfDelete = true;
775 if (part != null && part.ParentGroup != null) 775 if (part != null)
776 m_Engine.World.DeleteSceneObject(part.ParentGroup, false); 776 m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
777 } 777 }
778 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 778 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
779 { 779 {
780 m_InSelfDelete = true; 780 m_InSelfDelete = true;
781 if (part != null && part.ParentGroup != null) 781 if (part != null)
782 part.Inventory.RemoveInventoryItem(m_ItemID); 782 part.Inventory.RemoveInventoryItem(m_ItemID);
783 } 783 }
784 } 784 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 6bfee91..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -1373,7 +1373,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1373 public struct LSLString 1373 public struct LSLString
1374 { 1374 {
1375 public string m_string; 1375 public string m_string;
1376
1376 #region Constructors 1377 #region Constructors
1378
1377 public LSLString(string s) 1379 public LSLString(string s)
1378 { 1380 {
1379 m_string = s; 1381 m_string = s;
@@ -1381,22 +1383,24 @@ namespace OpenSim.Region.ScriptEngine.Shared
1381 1383
1382 public LSLString(double d) 1384 public LSLString(double d)
1383 { 1385 {
1384 string s=String.Format(Culture.FormatProvider, "{0:0.000000}", d); 1386 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d);
1385 m_string=s; 1387 m_string = s;
1386 } 1388 }
1387 1389
1388 public LSLString(LSLFloat f) 1390 public LSLString(LSLFloat f)
1389 { 1391 {
1390 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value); 1392 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
1391 m_string=s; 1393 m_string = s;
1392 } 1394 }
1393 1395
1394 public LSLString(LSLInteger i) 1396 public LSLString(int i)
1395 { 1397 {
1396 string s = String.Format("{0}", i); 1398 string s = String.Format("{0}", i);
1397 m_string = s; 1399 m_string = s;
1398 } 1400 }
1399 1401
1402 public LSLString(LSLInteger i) : this(i.value) {}
1403
1400 #endregion 1404 #endregion
1401 1405
1402 #region Operators 1406 #region Operators
@@ -1463,6 +1467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
1463 { 1467 {
1464 return new LSLString(d); 1468 return new LSLString(d);
1465 } 1469 }
1470
1471 static public explicit operator LSLString(int i)
1472 {
1473 return new LSLString(i);
1474 }
1466 1475
1467 public static explicit operator LSLString(LSLFloat f) 1476 public static explicit operator LSLString(LSLFloat f)
1468 { 1477 {
@@ -1736,7 +1745,17 @@ namespace OpenSim.Region.ScriptEngine.Shared
1736 public override bool Equals(Object o) 1745 public override bool Equals(Object o)
1737 { 1746 {
1738 if (!(o is LSLInteger)) 1747 if (!(o is LSLInteger))
1739 return false; 1748 {
1749 if (o is int)
1750 {
1751 return value == (int)o;
1752 }
1753 else
1754 {
1755 return false;
1756 }
1757 }
1758
1740 return value == ((LSLInteger)o).value; 1759 return value == ((LSLInteger)o).value;
1741 } 1760 }
1742 1761
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 80b60a4..0cbad41 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -27,11 +27,13 @@
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using NUnit.Framework; 29using NUnit.Framework;
30using OpenSim.Framework;
30using OpenSim.Tests.Common; 31using OpenSim.Tests.Common;
31using OpenSim.Region.ScriptEngine.Shared; 32using OpenSim.Region.ScriptEngine.Shared;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33using Nini.Config; 34using Nini.Config;
34using OpenSim.Region.ScriptEngine.Shared.Api; 35using OpenSim.Region.ScriptEngine.Shared.Api;
36using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
35using OpenMetaverse; 37using OpenMetaverse;
36using System; 38using System;
37using OpenSim.Tests.Common.Mock; 39using OpenSim.Tests.Common.Mock;
@@ -47,6 +49,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
47 49
48 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; 50 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
49 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d; 51 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
52 private const float FLOAT_ACCURACY = 0.00005f;
50 private LSL_Api m_lslApi; 53 private LSL_Api m_lslApi;
51 54
52 [SetUp] 55 [SetUp]
@@ -57,8 +60,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
57 IConfig config = initConfigSource.AddConfig("XEngine"); 60 IConfig config = initConfigSource.AddConfig("XEngine");
58 config.Set("Enabled", "true"); 61 config.Set("Enabled", "true");
59 62
60 Scene scene = SceneSetupHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
61 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 64 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
62 65
63 XEngine.XEngine engine = new XEngine.XEngine(); 66 XEngine.XEngine engine = new XEngine.XEngine();
64 engine.Initialise(initConfigSource); 67 engine.Initialise(initConfigSource);
@@ -166,6 +169,239 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
166 } 169 }
167 170
168 [Test] 171 [Test]
172 // llSetPrimitiveParams and llGetPrimitiveParams test.
173 public void TestllSetPrimitiveParams()
174 {
175 // Create Prim1.
176 Scene scene = SceneHelpers.SetupScene();
177 string obj1Name = "Prim1";
178 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
179 SceneObjectPart part1 =
180 new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default,
181 Vector3.Zero, Quaternion.Identity,
182 Vector3.Zero) { Name = obj1Name, UUID = objUuid };
183 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
184
185 // Note that prim hollow check is passed with the other prim params in order to allow the
186 // specification of a different check value from the prim param. A cylinder, prism, sphere,
187 // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below
188 // specifies a value of 95% and checks to see if 70% was properly returned.
189
190 // Test a sphere.
191 CheckllSetPrimitiveParams(
192 "test 1", // Prim test identification string
193 new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size
194 ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
195 ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
196 new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
197 0.80f, // Prim hollow
198 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
199 new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
200 0.80f); // Prim hollow check
201
202 // Test a prism.
203 CheckllSetPrimitiveParams(
204 "test 2", // Prim test identification string
205 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
206 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
207 ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
208 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
209 0.90f, // Prim hollow
210 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
211 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
212 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
213 0.90f); // Prim hollow check
214
215 // Test a box.
216 CheckllSetPrimitiveParams(
217 "test 3", // Prim test identification string
218 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
219 ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
220 ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
221 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
222 0.95f, // Prim hollow
223 new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
224 new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
225 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
226 0.95f); // Prim hollow check
227
228 // Test a tube.
229 CheckllSetPrimitiveParams(
230 "test 4", // Prim test identification string
231 new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size
232 ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
233 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
234 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
235 0.00f, // Prim hollow
236 new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
237 new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
238 // Expression for y selected to test precision problems during byte
239 // cast in SetPrimitiveShapeParams.
240 new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
241 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
242 // Expression for y selected to test precision problems during sbyte
243 // cast in SetPrimitiveShapeParams.
244 new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
245 1.11f, // Prim revolutions
246 0.88f, // Prim radius
247 0.95f, // Prim skew
248 0.00f); // Prim hollow check
249
250 // Test a prism.
251 CheckllSetPrimitiveParams(
252 "test 5", // Prim test identification string
253 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
254 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
255 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
256 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
257 0.95f, // Prim hollow
258 // Expression for x selected to test precision problems during sbyte
259 // cast in SetPrimitiveShapeBlockParams.
260 new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
261 // Expression for y selected to test precision problems during sbyte
262 // cast in SetPrimitiveShapeParams.
263 new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
264 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
265 0.70f); // Prim hollow check
266
267 // Test a sculpted prim.
268 CheckllSetPrimitiveParams(
269 "test 6", // Prim test identification string
270 new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size
271 ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type
272 "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map
273 ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type
274 }
275
276 // Set prim params for a box, cylinder or prism and check results.
277 public void CheckllSetPrimitiveParams(string primTest,
278 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
279 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
280 float primHollowCheck)
281 {
282 // Set the prim params.
283 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
284 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
285 primCut, primHollow, primTwist, primTaper, primShear));
286
287 // Get params for prim to validate settings.
288 LSL_Types.list primParams =
289 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
290
291 // Validate settings.
292 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
293 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
294 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
295 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
296 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
297 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
298 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
299 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
300 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
301 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper");
302 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
303 }
304
305 // Set prim params for a sphere and check results.
306 public void CheckllSetPrimitiveParams(string primTest,
307 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
308 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
309 {
310 // Set the prim params.
311 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
312 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
313 primCut, primHollow, primTwist, primDimple));
314
315 // Get params for prim to validate settings.
316 LSL_Types.list primParams =
317 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
318
319 // Validate settings.
320 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
321 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
322 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
323 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
324 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
325 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
326 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
327 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
328 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
329 CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple");
330 }
331
332 // Set prim params for a torus, tube or ring and check results.
333 public void CheckllSetPrimitiveParams(string primTest,
334 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
335 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
336 LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
337 float primRev, float primRadius, float primSkew, float primHollowCheck)
338 {
339 // Set the prim params.
340 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
341 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
342 primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut,
343 primTaper, primRev, primRadius, primSkew));
344
345 // Get params for prim to validate settings.
346 LSL_Types.list primParams =
347 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
348
349 // Valdate settings.
350 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
351 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
352 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
353 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
354 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
355 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
356 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
357 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
358 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
359 CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size");
360 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
361 CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
362 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
363 Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
364 "TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
365 Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
366 "TestllSetPrimitiveParams " + primTest + " prim radius fail");
367 Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
368 "TestllSetPrimitiveParams " + primTest + " prim skew fail");
369 }
370
371 // Set prim params for a sculpted prim and check results.
372 public void CheckllSetPrimitiveParams(string primTest,
373 LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType)
374 {
375 // Set the prim params.
376 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
377 ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType));
378
379 // Get params for prim to validate settings.
380 LSL_Types.list primParams =
381 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
382
383 // Validate settings.
384 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
385 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
386 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
387 Assert.AreEqual(primMap, (string)m_lslApi.llList2String(primParams, 2),
388 "TestllSetPrimitiveParams " + primTest + " prim map check fail");
389 Assert.AreEqual(primSculptType, m_lslApi.llList2Integer(primParams, 3),
390 "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail");
391 }
392
393 public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg)
394 {
395 // Check each vector component against expected result.
396 Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY,
397 "TestllSetPrimitiveParams " + msg + " vector check fail on x component");
398 Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY,
399 "TestllSetPrimitiveParams " + msg + " vector check fail on y component");
400 Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY,
401 "TestllSetPrimitiveParams " + msg + " vector check fail on z component");
402 }
403
404 [Test]
169 // llVecNorm test. 405 // llVecNorm test.
170 public void TestllVecNorm() 406 public void TestllVecNorm()
171 { 407 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
new file mode 100644
index 0000000..7573dff
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -0,0 +1,229 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47
48namespace OpenSim.Region.ScriptEngine.Shared.Tests
49{
50 /// <summary>
51 /// Tests for OSSL_Api
52 /// </summary>
53 [TestFixture]
54 public class OSSL_ApiAppearanceTest
55 {
56 protected Scene m_scene;
57 protected XEngine.XEngine m_engine;
58
59 [SetUp]
60 public void SetUp()
61 {
62 IConfigSource initConfigSource = new IniConfigSource();
63 IConfig config = initConfigSource.AddConfig("XEngine");
64 config.Set("Enabled", "true");
65 config.Set("AllowOSFunctions", "true");
66 config.Set("OSFunctionThreatLevel", "Severe");
67 config = initConfigSource.AddConfig("NPC");
68 config.Set("Enabled", "true");
69
70 m_scene = SceneHelpers.SetupScene();
71 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
72
73 m_engine = new XEngine.XEngine();
74 m_engine.Initialise(initConfigSource);
75 m_engine.AddRegion(m_scene);
76 }
77
78 /// <summary>
79 /// Test creation of an NPC where the appearance data comes from a notecard
80 /// </summary>
81 [Test]
82 public void TestOsNpcCreateFromNotecard()
83 {
84 TestHelpers.InMethod();
85// log4net.Config.XmlConfigurator.Configure();
86
87 // Store an avatar with a different height from default in a notecard.
88 UUID userId = TestHelpers.ParseTail(0x1);
89 float newHeight = 1.9f;
90
91 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
92 sp.Appearance.AvatarHeight = newHeight;
93 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
94 SceneObjectPart part = so.RootPart;
95 m_scene.AddSceneObject(so);
96
97 OSSL_Api osslApi = new OSSL_Api();
98 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
99
100 string notecardName = "appearanceNc";
101 osslApi.osOwnerSaveAppearance(notecardName);
102
103 // Try creating a bot using the appearance in the notecard.
104 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
105 Assert.That(npcRaw, Is.Not.Null);
106
107 UUID npcId = new UUID(npcRaw);
108 ScenePresence npc = m_scene.GetScenePresence(npcId);
109 Assert.That(npc, Is.Not.Null);
110 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
111 }
112
113 /// <summary>
114 /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
115 /// </summary>
116 [Test]
117 public void TestOsNpcCreateFromAvatar()
118 {
119 TestHelpers.InMethod();
120// log4net.Config.XmlConfigurator.Configure();
121
122 // Store an avatar with a different height from default in a notecard.
123 UUID userId = TestHelpers.ParseTail(0x1);
124 float newHeight = 1.9f;
125
126 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
127 sp.Appearance.AvatarHeight = newHeight;
128 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
129 SceneObjectPart part = so.RootPart;
130 m_scene.AddSceneObject(so);
131
132 OSSL_Api osslApi = new OSSL_Api();
133 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
134
135 string notecardName = "appearanceNc";
136 osslApi.osOwnerSaveAppearance(notecardName);
137
138 // Try creating a bot using the existing avatar's appearance
139 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
140 Assert.That(npcRaw, Is.Not.Null);
141
142 UUID npcId = new UUID(npcRaw);
143 ScenePresence npc = m_scene.GetScenePresence(npcId);
144 Assert.That(npc, Is.Not.Null);
145 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
146 }
147
148 [Test]
149 public void TestOsOwnerSaveAppearance()
150 {
151 TestHelpers.InMethod();
152// log4net.Config.XmlConfigurator.Configure();
153
154 UUID userId = TestHelpers.ParseTail(0x1);
155 float newHeight = 1.9f;
156
157 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
158 sp.Appearance.AvatarHeight = newHeight;
159 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
160 SceneObjectPart part = so.RootPart;
161 m_scene.AddSceneObject(so);
162
163 OSSL_Api osslApi = new OSSL_Api();
164 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
165
166 string notecardName = "appearanceNc";
167
168 osslApi.osOwnerSaveAppearance(notecardName);
169
170 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
171 Assert.That(items.Count, Is.EqualTo(1));
172
173 TaskInventoryItem ncItem = items[0];
174 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
175
176 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
177 Assert.That(ncAsset, Is.Not.Null);
178
179 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
180 anc.Decode();
181 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
182 AvatarAppearance savedAppearance = new AvatarAppearance();
183 savedAppearance.Unpack(appearanceOsd);
184
185 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
186 }
187
188 [Test]
189 public void TestOsAgentSaveAppearance()
190 {
191 TestHelpers.InMethod();
192// log4net.Config.XmlConfigurator.Configure();
193
194 UUID ownerId = TestHelpers.ParseTail(0x1);
195 UUID nonOwnerId = TestHelpers.ParseTail(0x2);
196 float newHeight = 1.9f;
197
198 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId);
199 sp.Appearance.AvatarHeight = newHeight;
200 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId);
201 SceneObjectPart part = so.RootPart;
202 m_scene.AddSceneObject(so);
203
204 OSSL_Api osslApi = new OSSL_Api();
205 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
206
207 string notecardName = "appearanceNc";
208
209 osslApi.osAgentSaveAppearance(new LSL_Types.LSLString(nonOwnerId.ToString()), notecardName);
210
211 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
212 Assert.That(items.Count, Is.EqualTo(1));
213
214 TaskInventoryItem ncItem = items[0];
215 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
216
217 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
218 Assert.That(ncAsset, Is.Not.Null);
219
220 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
221 anc.Decode();
222 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
223 AvatarAppearance savedAppearance = new AvatarAppearance();
224 savedAppearance.Unpack(appearanceOsd);
225
226 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
227 }
228 }
229} \ No newline at end of file