diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.IO; | ||
32 | using System.Reflection; | ||
31 | using System.Runtime.Remoting.Lifetime; | 33 | using System.Runtime.Remoting.Lifetime; |
32 | using System.Text; | 34 | using System.Text; |
33 | using System.Net; | 35 | using System.Net; |
34 | using System.Threading; | 36 | using System.Threading; |
37 | using System.Xml; | ||
38 | using log4net; | ||
35 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | using OpenMetaverse.StructuredData; | ||
36 | using Nini.Config; | 41 | using Nini.Config; |
37 | using OpenSim; | 42 | using OpenSim; |
38 | using OpenSim.Framework; | 43 | using 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 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using NUnit.Framework; | 29 | using NUnit.Framework; |
30 | using OpenSim.Framework; | ||
30 | using OpenSim.Tests.Common; | 31 | using OpenSim.Tests.Common; |
31 | using OpenSim.Region.ScriptEngine.Shared; | 32 | using OpenSim.Region.ScriptEngine.Shared; |
32 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
33 | using Nini.Config; | 34 | using Nini.Config; |
34 | using OpenSim.Region.ScriptEngine.Shared.Api; | 35 | using OpenSim.Region.ScriptEngine.Shared.Api; |
36 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
35 | using OpenMetaverse; | 37 | using OpenMetaverse; |
36 | using System; | 38 | using System; |
37 | using OpenSim.Tests.Common.Mock; | 39 | using 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenMetaverse.Assets; | ||
37 | using OpenMetaverse.StructuredData; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Region.CoreModules.Avatar.AvatarFactory; | ||
40 | using OpenSim.Region.OptionalModules.World.NPC; | ||
41 | using OpenSim.Region.Framework.Scenes; | ||
42 | using OpenSim.Region.ScriptEngine.Shared; | ||
43 | using OpenSim.Region.ScriptEngine.Shared.Api; | ||
44 | using OpenSim.Services.Interfaces; | ||
45 | using OpenSim.Tests.Common; | ||
46 | using OpenSim.Tests.Common.Mock; | ||
47 | |||
48 | namespace 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 | ||