aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2982
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
15 files changed, 2624 insertions, 870 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index deb68b8..2700495 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116 protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
109 118
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 119 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 120 {
121 m_ShoutSayTimer = new Timer(1000);
122 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
123 m_ShoutSayTimer.AutoReset = true;
124 m_ShoutSayTimer.Start();
125
112 m_ScriptEngine = ScriptEngine; 126 m_ScriptEngine = ScriptEngine;
113 m_host = host; 127 m_host = host;
114 m_item = item; 128 m_item = item;
129 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 130
116 LoadLimits(); // read script limits from config. 131 LoadLimits(); // read script limits from config.
117 132
@@ -171,6 +186,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 186 get { return m_ScriptEngine.World; }
172 } 187 }
173 188
189 [DebuggerNonUserCode]
174 public void state(string newState) 190 public void state(string newState)
175 { 191 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 192 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 196 /// Reset the named script. The script must be present
181 /// in the same prim. 197 /// in the same prim.
182 /// </summary> 198 /// </summary>
199 [DebuggerNonUserCode]
183 public void llResetScript() 200 public void llResetScript()
184 { 201 {
185 m_host.AddScriptLPS(1); 202 m_host.AddScriptLPS(1);
@@ -236,9 +253,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 253 }
237 } 254 }
238 255
256 public List<ScenePresence> GetLinkAvatars(int linkType)
257 {
258 List<ScenePresence> ret = new List<ScenePresence>();
259 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
260 return ret;
261
262 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
263
264 switch (linkType)
265 {
266 case ScriptBaseClass.LINK_SET:
267 return avs;
268
269 case ScriptBaseClass.LINK_ROOT:
270 return ret;
271
272 case ScriptBaseClass.LINK_ALL_OTHERS:
273 return avs;
274
275 case ScriptBaseClass.LINK_ALL_CHILDREN:
276 return avs;
277
278 case ScriptBaseClass.LINK_THIS:
279 return ret;
280
281 default:
282 if (linkType < 0)
283 return ret;
284
285 int partCount = m_host.ParentGroup.GetPartCount();
286
287 if (linkType <= partCount)
288 {
289 return ret;
290 }
291 else
292 {
293 linkType = linkType - partCount;
294 if (linkType > avs.Count)
295 {
296 return ret;
297 }
298 else
299 {
300 ret.Add(avs[linkType-1]);
301 return ret;
302 }
303 }
304 }
305 }
306
239 public List<SceneObjectPart> GetLinkParts(int linkType) 307 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 308 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 309 List<SceneObjectPart> ret = new List<SceneObjectPart>();
310 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
311 return ret;
242 ret.Add(m_host); 312 ret.Add(m_host);
243 313
244 switch (linkType) 314 switch (linkType)
@@ -432,31 +502,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
432 502
433 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 503 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
434 504
435 /// <summary> 505 // Utility function for llRot2Euler
436 /// Convert an LSL rotation to a Euler vector. 506
437 /// </summary> 507 // normalize an angle between -PI and PI (-180 to +180 degrees)
438 /// <remarks> 508 protected double NormalizeAngle(double angle)
439 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
440 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
441 /// </remarks>
442 /// <param name="r"></param>
443 /// <returns></returns>
444 public LSL_Vector llRot2Euler(LSL_Rotation r)
445 { 509 {
446 m_host.AddScriptLPS(1); 510 if (angle > -Math.PI && angle < Math.PI)
511 return angle;
512
513 int numPis = (int)(Math.PI / angle);
514 double remainder = angle - Math.PI * numPis;
515 if (numPis % 2 == 1)
516 return Math.PI - angle;
517 return remainder;
518 }
447 519
448 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 520 public LSL_Vector llRot2Euler(LSL_Rotation q1)
449 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 521 {
450 if (m == 0.0) return new LSL_Vector(); 522 m_host.AddScriptLPS(1);
451 double x = Math.Atan2(-v.y, v.z); 523 LSL_Vector eul = new LSL_Vector();
452 double sin = v.x / m;
453 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
454 double y = Math.Asin(sin);
455 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
456 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
457 double z = Math.Atan2(v.y, v.x);
458 524
459 return new LSL_Vector(x, y, z); 525 double sqw = q1.s*q1.s;
526 double sqx = q1.x*q1.x;
527 double sqy = q1.z*q1.z;
528 double sqz = q1.y*q1.y;
529 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
530 double test = q1.x*q1.z + q1.y*q1.s;
531 if (test > 0.4999*unit) { // singularity at north pole
532 eul.z = 2 * Math.Atan2(q1.x,q1.s);
533 eul.y = Math.PI/2;
534 eul.x = 0;
535 return eul;
536 }
537 if (test < -0.4999*unit) { // singularity at south pole
538 eul.z = -2 * Math.Atan2(q1.x,q1.s);
539 eul.y = -Math.PI/2;
540 eul.x = 0;
541 return eul;
542 }
543 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
544 eul.y = Math.Asin(2*test/unit);
545 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
546 return eul;
460 } 547 }
461 548
462 /* From wiki: 549 /* From wiki:
@@ -658,77 +745,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
658 { 745 {
659 //A and B should both be normalized 746 //A and B should both be normalized
660 m_host.AddScriptLPS(1); 747 m_host.AddScriptLPS(1);
661 LSL_Rotation rotBetween; 748 /* This method is more accurate than the SL one, and thus causes problems
662 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 749 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
663 // continue calculation. 750
664 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 751 double dotProduct = LSL_Vector.Dot(a, b);
752 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
753 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
754 double angle = Math.Acos(dotProduct / magProduct);
755 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
756 double s = Math.Sin(angle / 2);
757
758 double x = axis.x * s;
759 double y = axis.y * s;
760 double z = axis.z * s;
761 double w = Math.Cos(angle / 2);
762
763 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
764 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
765
766 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
767 */
768
769 // This method mimics the 180 errors found in SL
770 // See www.euclideanspace.com... angleBetween
771 LSL_Vector vec_a = a;
772 LSL_Vector vec_b = b;
773
774 // Eliminate zero length
775 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
776 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
777 if (vec_a_mag < 0.00001 ||
778 vec_b_mag < 0.00001)
665 { 779 {
666 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 780 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
667 } 781 }
668 else 782
783 // Normalize
784 vec_a = llVecNorm(vec_a);
785 vec_b = llVecNorm(vec_b);
786
787 // Calculate axis and rotation angle
788 LSL_Vector axis = vec_a % vec_b;
789 LSL_Float cos_theta = vec_a * vec_b;
790
791 // Check if parallel
792 if (cos_theta > 0.99999)
669 { 793 {
670 a = LSL_Vector.Norm(a); 794 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
671 b = LSL_Vector.Norm(b); 795 }
672 double dotProduct = LSL_Vector.Dot(a, b); 796
673 // There are two degenerate cases possible. These are for vectors 180 or 797 // Check if anti-parallel
674 // 0 degrees apart. These have to be detected and handled individually. 798 else if (cos_theta < -0.99999)
675 // 799 {
676 // Check for vectors 180 degrees apart. 800 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
677 // A dot product of -1 would mean the angle between vectors is 180 degrees. 801 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
678 if (dotProduct < -0.9999999f) 802 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
679 { 803 }
680 // First assume X axis is orthogonal to the vectors. 804 else // other rotation
681 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 805 {
682 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 806 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
683 // Check for near zero vector. A very small non-zero number here will create 807 axis = llVecNorm(axis);
684 // a rotation in an undesired direction. 808 double x, y, z, s, t;
685 if (LSL_Vector.Mag(orthoVector) > 0.0001) 809 s = Math.Cos(theta);
686 { 810 t = Math.Sin(theta);
687 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 811 x = axis.x * t;
688 } 812 y = axis.y * t;
689 // If the magnitude of the vector was near zero, then assume the X axis is not 813 z = axis.z * t;
690 // orthogonal and use the Z axis instead. 814 return new LSL_Rotation(x,y,z,s);
691 else
692 {
693 // Set 180 z rotation.
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
695 }
696 }
697 // Check for parallel vectors.
698 // A dot product of 1 would mean the angle between vectors is 0 degrees.
699 else if (dotProduct > 0.9999999f)
700 {
701 // Set zero rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
703 }
704 else
705 {
706 // All special checks have been performed so get the axis of rotation.
707 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
708 // Quarternion s value is the length of the unit vector + dot product.
709 double qs = 1.0 + dotProduct;
710 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
711 // Normalize the rotation.
712 double mag = LSL_Rotation.Mag(rotBetween);
713 // We shouldn't have to worry about a divide by zero here. The qs value will be
714 // non-zero because we already know if we're here, then the dotProduct is not -1 so
715 // qs will not be zero. Also, we've already handled the input vectors being zero so the
716 // crossProduct vector should also not be zero.
717 rotBetween.x = rotBetween.x / mag;
718 rotBetween.y = rotBetween.y / mag;
719 rotBetween.z = rotBetween.z / mag;
720 rotBetween.s = rotBetween.s / mag;
721 // Check for undefined values and set zero rotation if any found. This code might not actually be required
722 // any longer since zero vectors are checked for at the top.
723 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
724 {
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
726 }
727 }
728 } 815 }
729 return rotBetween;
730 } 816 }
731 817
732 public void llWhisper(int channelID, string text) 818 public void llWhisper(int channelID, string text)
733 { 819 {
734 m_host.AddScriptLPS(1); 820 m_host.AddScriptLPS(1);
@@ -748,6 +834,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
748 { 834 {
749 m_host.AddScriptLPS(1); 835 m_host.AddScriptLPS(1);
750 836
837 if (channelID == 0)
838 m_SayShoutCount++;
839
840 if (m_SayShoutCount >= 11)
841 ScriptSleep(2000);
842
751 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 843 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
752 { 844 {
753 Console.WriteLine(text); 845 Console.WriteLine(text);
@@ -770,6 +862,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
770 { 862 {
771 m_host.AddScriptLPS(1); 863 m_host.AddScriptLPS(1);
772 864
865 if (channelID == 0)
866 m_SayShoutCount++;
867
868 if (m_SayShoutCount >= 11)
869 ScriptSleep(2000);
870
773 if (text.Length > 1023) 871 if (text.Length > 1023)
774 text = text.Substring(0, 1023); 872 text = text.Substring(0, 1023);
775 873
@@ -1072,10 +1170,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1072 return detectedParams.TouchUV; 1170 return detectedParams.TouchUV;
1073 } 1171 }
1074 1172
1173 [DebuggerNonUserCode]
1075 public virtual void llDie() 1174 public virtual void llDie()
1076 { 1175 {
1077 m_host.AddScriptLPS(1); 1176 m_host.AddScriptLPS(1);
1078 throw new SelfDeleteException(); 1177 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1079 } 1178 }
1080 1179
1081 public LSL_Float llGround(LSL_Vector offset) 1180 public LSL_Float llGround(LSL_Vector offset)
@@ -1148,6 +1247,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1148 1247
1149 public void llSetStatus(int status, int value) 1248 public void llSetStatus(int status, int value)
1150 { 1249 {
1250 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1251 return;
1151 m_host.AddScriptLPS(1); 1252 m_host.AddScriptLPS(1);
1152 1253
1153 int statusrotationaxis = 0; 1254 int statusrotationaxis = 0;
@@ -1171,6 +1272,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1171 if (!allow) 1272 if (!allow)
1172 return; 1273 return;
1173 1274
1275 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1276 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1277 return;
1278
1174 m_host.ScriptSetPhysicsStatus(true); 1279 m_host.ScriptSetPhysicsStatus(true);
1175 } 1280 }
1176 else 1281 else
@@ -1379,6 +1484,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1379 { 1484 {
1380 m_host.AddScriptLPS(1); 1485 m_host.AddScriptLPS(1);
1381 1486
1487 SetColor(m_host, color, face);
1488 }
1489
1490 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1491 {
1492 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1493 return;
1494
1495 Primitive.TextureEntry tex = part.Shape.Textures;
1496 Color4 texcolor;
1497 if (face >= 0 && face < GetNumberOfSides(part))
1498 {
1499 texcolor = tex.CreateFace((uint)face).RGBA;
1500 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1501 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1502 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1503 tex.FaceTextures[face].RGBA = texcolor;
1504 part.UpdateTextureEntry(tex.GetBytes());
1505 return;
1506 }
1507 else if (face == ScriptBaseClass.ALL_SIDES)
1508 {
1509 for (uint i = 0; i < GetNumberOfSides(part); i++)
1510 {
1511 if (tex.FaceTextures[i] != null)
1512 {
1513 texcolor = tex.FaceTextures[i].RGBA;
1514 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1515 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1516 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1517 tex.FaceTextures[i].RGBA = texcolor;
1518 }
1519 texcolor = tex.DefaultTexture.RGBA;
1520 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1521 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1522 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1523 tex.DefaultTexture.RGBA = texcolor;
1524 }
1525 part.UpdateTextureEntry(tex.GetBytes());
1526 return;
1527 }
1528
1382 if (face == ScriptBaseClass.ALL_SIDES) 1529 if (face == ScriptBaseClass.ALL_SIDES)
1383 face = SceneObjectPart.ALL_SIDES; 1530 face = SceneObjectPart.ALL_SIDES;
1384 1531
@@ -1387,6 +1534,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 1534
1388 public void SetTexGen(SceneObjectPart part, int face,int style) 1535 public void SetTexGen(SceneObjectPart part, int face,int style)
1389 { 1536 {
1537 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1538 return;
1539
1390 Primitive.TextureEntry tex = part.Shape.Textures; 1540 Primitive.TextureEntry tex = part.Shape.Textures;
1391 MappingType textype; 1541 MappingType textype;
1392 textype = MappingType.Default; 1542 textype = MappingType.Default;
@@ -1417,6 +1567,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 1567
1418 public void SetGlow(SceneObjectPart part, int face, float glow) 1568 public void SetGlow(SceneObjectPart part, int face, float glow)
1419 { 1569 {
1570 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1571 return;
1572
1420 Primitive.TextureEntry tex = part.Shape.Textures; 1573 Primitive.TextureEntry tex = part.Shape.Textures;
1421 if (face >= 0 && face < GetNumberOfSides(part)) 1574 if (face >= 0 && face < GetNumberOfSides(part))
1422 { 1575 {
@@ -1442,6 +1595,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 1595
1443 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1596 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1444 { 1597 {
1598 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1599 return;
1445 1600
1446 Shininess sval = new Shininess(); 1601 Shininess sval = new Shininess();
1447 1602
@@ -1492,6 +1647,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 1647
1493 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1648 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1494 { 1649 {
1650 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return;
1652
1495 Primitive.TextureEntry tex = part.Shape.Textures; 1653 Primitive.TextureEntry tex = part.Shape.Textures;
1496 if (face >= 0 && face < GetNumberOfSides(part)) 1654 if (face >= 0 && face < GetNumberOfSides(part))
1497 { 1655 {
@@ -1552,13 +1710,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1552 m_host.AddScriptLPS(1); 1710 m_host.AddScriptLPS(1);
1553 1711
1554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1712 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1555 1713 if (parts.Count > 0)
1556 foreach (SceneObjectPart part in parts) 1714 {
1557 SetAlpha(part, alpha, face); 1715 try
1716 {
1717 parts[0].ParentGroup.areUpdatesSuspended = true;
1718 foreach (SceneObjectPart part in parts)
1719 SetAlpha(part, alpha, face);
1720 }
1721 finally
1722 {
1723 parts[0].ParentGroup.areUpdatesSuspended = false;
1724 }
1725 }
1558 } 1726 }
1559 1727
1560 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1728 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1561 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1732
1562 Primitive.TextureEntry tex = part.Shape.Textures; 1733 Primitive.TextureEntry tex = part.Shape.Textures;
1563 Color4 texcolor; 1734 Color4 texcolor;
1564 if (face >= 0 && face < GetNumberOfSides(part)) 1735 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1611,7 +1782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1782 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1612 float wind, float tension, LSL_Vector Force) 1783 float wind, float tension, LSL_Vector Force)
1613 { 1784 {
1614 if (part == null) 1785 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1786 return;
1616 1787
1617 if (flexi) 1788 if (flexi)
@@ -1645,7 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1816 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1817 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1818 {
1648 if (part == null) 1819 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1820 return;
1650 1821
1651 if (light) 1822 if (light)
@@ -1724,15 +1895,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 m_host.AddScriptLPS(1); 1895 m_host.AddScriptLPS(1);
1725 1896
1726 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1897 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1727 1898 if (parts.Count > 0)
1728 foreach (SceneObjectPart part in parts) 1899 {
1729 SetTexture(part, texture, face); 1900 try
1730 1901 {
1902 parts[0].ParentGroup.areUpdatesSuspended = true;
1903 foreach (SceneObjectPart part in parts)
1904 SetTexture(part, texture, face);
1905 }
1906 finally
1907 {
1908 parts[0].ParentGroup.areUpdatesSuspended = false;
1909 }
1910 }
1731 ScriptSleep(200); 1911 ScriptSleep(200);
1732 } 1912 }
1733 1913
1734 protected void SetTexture(SceneObjectPart part, string texture, int face) 1914 protected void SetTexture(SceneObjectPart part, string texture, int face)
1735 { 1915 {
1916 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1917 return;
1918
1736 UUID textureID = new UUID(); 1919 UUID textureID = new UUID();
1737 1920
1738 textureID = InventoryKey(texture, (int)AssetType.Texture); 1921 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1777,6 +1960,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1777 1960
1778 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1961 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1779 { 1962 {
1963 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1964 return;
1965
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1966 Primitive.TextureEntry tex = part.Shape.Textures;
1781 if (face >= 0 && face < GetNumberOfSides(part)) 1967 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 1968 {
@@ -1813,6 +1999,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 1999
1814 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2000 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2001 {
2002 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2003 return;
2004
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2005 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2006 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2007 {
@@ -1849,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2038
1850 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2039 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1851 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2046 {
@@ -1953,26 +2145,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 return real_vec; 2145 return real_vec;
1954 } 2146 }
1955 2147
2148 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2149 {
2150 return new LSL_Integer(SetRegionPos(m_host, pos));
2151 }
2152
2153 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2154 {
2155 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2156 return 0;
2157
2158 SceneObjectGroup grp = part.ParentGroup;
2159
2160 if (grp.IsAttachment)
2161 return 0;
2162
2163 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2164 return 0;
2165
2166 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2167 return 0;
2168
2169 float constrainedX = (float)targetPos.x;
2170 float constrainedY = (float)targetPos.y;
2171
2172 if (constrainedX < 0.0f)
2173 constrainedX = 0.0f;
2174 if (constrainedY < 0.0f)
2175 constrainedY = 0.0f;
2176 if (constrainedX >= (float)Constants.RegionSize)
2177 constrainedX = (float)Constants.RegionSize - 0.1f;
2178 if (constrainedY >= (float)Constants.RegionSize)
2179 constrainedY = (float)Constants.RegionSize -0.1f;
2180
2181 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2182
2183 if (targetPos.z < ground)
2184 targetPos.z = ground;
2185
2186 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2187
2188 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2189 return 0;
2190
2191 grp.UpdateGroupPosition(dest);
2192
2193 return 1;
2194 }
2195
1956 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2196 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1957 { 2197 {
1958 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2198 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2199 return;
2200
1959 LSL_Vector currentPos = GetPartLocalPos(part); 2201 LSL_Vector currentPos = GetPartLocalPos(part);
2202 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1960 2203
1961 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1962 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1963 2204
1964 if (part.ParentGroup.RootPart == part) 2205 if (part.ParentGroup.RootPart == part)
1965 { 2206 {
1966 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1967 targetPos.z = ground;
1968 SceneObjectGroup parent = part.ParentGroup; 2207 SceneObjectGroup parent = part.ParentGroup;
1969 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2208 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1970 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2209 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2210 return;
2211 Util.FireAndForget(delegate(object x) {
2212 parent.UpdateGroupPosition(dest);
2213 });
1971 } 2214 }
1972 else 2215 else
1973 { 2216 {
1974 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2217 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1975 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1976 SceneObjectGroup parent = part.ParentGroup; 2218 SceneObjectGroup parent = part.ParentGroup;
1977 parent.HasGroupChanged = true; 2219 parent.HasGroupChanged = true;
1978 parent.ScheduleGroupForTerseUpdate(); 2220 parent.ScheduleGroupForTerseUpdate();
@@ -2005,17 +2247,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2005 else 2247 else
2006 { 2248 {
2007 if (part.ParentGroup.IsAttachment) 2249 if (part.ParentGroup.IsAttachment)
2008 {
2009 pos = part.AttachedPos; 2250 pos = part.AttachedPos;
2010 }
2011 else 2251 else
2012 {
2013 pos = part.AbsolutePosition; 2252 pos = part.AbsolutePosition;
2014 }
2015 } 2253 }
2016 2254
2017// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2018
2019 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2255 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2020 } 2256 }
2021 2257
@@ -2024,9 +2260,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 m_host.AddScriptLPS(1); 2260 m_host.AddScriptLPS(1);
2025 2261
2026 // try to let this work as in SL... 2262 // try to let this work as in SL...
2027 if (m_host.ParentID == 0) 2263 if (m_host.LinkNum < 2)
2028 { 2264 {
2029 // special case: If we are root, rotate complete SOG to new rotation 2265 // Special case: If we are root, rotate complete SOG to new
2266 // rotation.
2267 // We are root if the link number is 0 (single prim) or 1
2268 // (root prim). ParentID may be nonzero in attachments and
2269 // using it would cause attachments and HUDs to rotate
2270 // to the wrong positions.
2030 SetRot(m_host, Rot2Quaternion(rot)); 2271 SetRot(m_host, Rot2Quaternion(rot));
2031 } 2272 }
2032 else 2273 else
@@ -2051,6 +2292,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 2292
2052 protected void SetRot(SceneObjectPart part, Quaternion rot) 2293 protected void SetRot(SceneObjectPart part, Quaternion rot)
2053 { 2294 {
2295 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2296 return;
2297
2054 part.UpdateRotation(rot); 2298 part.UpdateRotation(rot);
2055 // Update rotation does not move the object in the physics scene if it's a linkset. 2299 // Update rotation does not move the object in the physics scene if it's a linkset.
2056 2300
@@ -2205,13 +2449,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2205 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2449 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2206 { 2450 {
2207 m_host.AddScriptLPS(1); 2451 m_host.AddScriptLPS(1);
2208 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2452 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2209 } 2453 }
2210 2454
2211 public void llSetTorque(LSL_Vector torque, int local) 2455 public void llSetTorque(LSL_Vector torque, int local)
2212 { 2456 {
2213 m_host.AddScriptLPS(1); 2457 m_host.AddScriptLPS(1);
2214 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2458 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2215 } 2459 }
2216 2460
2217 public LSL_Vector llGetTorque() 2461 public LSL_Vector llGetTorque()
@@ -2813,35 +3057,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 public void llLookAt(LSL_Vector target, double strength, double damping) 3057 public void llLookAt(LSL_Vector target, double strength, double damping)
2814 { 3058 {
2815 m_host.AddScriptLPS(1); 3059 m_host.AddScriptLPS(1);
2816 // Determine where we are looking from
2817 LSL_Vector from = llGetPos();
2818 3060
2819 // Work out the normalised vector from the source to the target 3061 // Get the normalized vector to the target
2820 LSL_Vector delta = llVecNorm(target - from); 3062 LSL_Vector d1 = llVecNorm(target - llGetPos());
2821 LSL_Vector angle = new LSL_Vector(0,0,0);
2822 3063
2823 // Calculate the yaw 3064 // Get the bearing (yaw)
2824 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3065 LSL_Vector a1 = new LSL_Vector(0,0,0);
2825 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3066 a1.z = llAtan2(d1.y, d1.x);
2826 3067
2827 // Calculate pitch 3068 // Get the elevation (pitch)
2828 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3069 LSL_Vector a2 = new LSL_Vector(0,0,0);
3070 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2829 3071
2830 // we need to convert from a vector describing 3072 LSL_Rotation r1 = llEuler2Rot(a1);
2831 // the angles of rotation in radians into rotation value 3073 LSL_Rotation r2 = llEuler2Rot(a2);
2832 LSL_Rotation rot = llEuler2Rot(angle); 3074 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2833
2834 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2835 // set the rotation of the object, copy that behavior
2836 PhysicsActor pa = m_host.PhysActor;
2837 3075
2838 if (strength == 0 || pa == null || !pa.IsPhysical) 3076 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2839 { 3077 {
2840 llSetRot(rot); 3078 // Do nothing if either value is 0 (this has been checked in SL)
3079 if (strength <= 0.0 || damping <= 0.0)
3080 return;
3081
3082 llSetRot(r3 * r2 * r1);
2841 } 3083 }
2842 else 3084 else
2843 { 3085 {
2844 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3086 if (strength == 0)
3087 {
3088 llSetRot(r3 * r2 * r1);
3089 return;
3090 }
3091
3092 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2845 } 3093 }
2846 } 3094 }
2847 3095
@@ -2887,17 +3135,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2887 } 3135 }
2888 else 3136 else
2889 { 3137 {
2890 if (m_host.IsRoot) 3138 // new SL always returns object mass
2891 { 3139// if (m_host.IsRoot)
3140// {
2892 return m_host.ParentGroup.GetMass(); 3141 return m_host.ParentGroup.GetMass();
2893 } 3142// }
2894 else 3143// else
2895 { 3144// {
2896 return m_host.GetMass(); 3145// return m_host.GetMass();
2897 } 3146// }
2898 } 3147 }
2899 } 3148 }
2900 3149
3150
3151 public LSL_Float llGetMassMKS()
3152 {
3153 return 100f * llGetMass();
3154 }
3155
2901 public void llCollisionFilter(string name, string id, int accept) 3156 public void llCollisionFilter(string name, string id, int accept)
2902 { 3157 {
2903 m_host.AddScriptLPS(1); 3158 m_host.AddScriptLPS(1);
@@ -3005,9 +3260,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3005 { 3260 {
3006 m_host.AddScriptLPS(1); 3261 m_host.AddScriptLPS(1);
3007 3262
3008// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3009// return;
3010
3011 if (m_item.PermsGranter != m_host.OwnerID) 3263 if (m_item.PermsGranter != m_host.OwnerID)
3012 return; 3264 return;
3013 3265
@@ -3050,6 +3302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 3302
3051 public void llInstantMessage(string user, string message) 3303 public void llInstantMessage(string user, string message)
3052 { 3304 {
3305 UUID result;
3306 if (!UUID.TryParse(user, out result))
3307 {
3308 ShoutError("An invalid key was passed to llInstantMessage");
3309 ScriptSleep(2000);
3310 return;
3311 }
3312
3313
3053 m_host.AddScriptLPS(1); 3314 m_host.AddScriptLPS(1);
3054 3315
3055 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3316 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3064,14 +3325,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 UUID friendTransactionID = UUID.Random(); 3325 UUID friendTransactionID = UUID.Random();
3065 3326
3066 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3327 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3067 3328
3068 GridInstantMessage msg = new GridInstantMessage(); 3329 GridInstantMessage msg = new GridInstantMessage();
3069 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3330 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3070 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3331 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3071 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3332 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3072// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3333// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3073// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3334// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3074 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3335// DateTime dt = DateTime.UtcNow;
3336//
3337// // Ticks from UtcNow, but make it look like local. Evil, huh?
3338// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3339//
3340// try
3341// {
3342// // Convert that to the PST timezone
3343// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3344// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3345// }
3346// catch
3347// {
3348// // No logging here, as it could be VERY spammy
3349// }
3350//
3351// // And make it look local again to fool the unix time util
3352// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3353
3354 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3355
3075 //if (client != null) 3356 //if (client != null)
3076 //{ 3357 //{
3077 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3358 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3085,12 +3366,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3085 msg.message = message.Substring(0, 1024); 3366 msg.message = message.Substring(0, 1024);
3086 else 3367 else
3087 msg.message = message; 3368 msg.message = message;
3088 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3369 msg.dialog = (byte)19; // MessageFromObject
3089 msg.fromGroup = false;// fromGroup; 3370 msg.fromGroup = false;// fromGroup;
3090 msg.offline = (byte)0; //offline; 3371 msg.offline = (byte)0; //offline;
3091 msg.ParentEstateID = 0; //ParentEstateID; 3372 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3092 msg.Position = new Vector3(m_host.AbsolutePosition); 3373 msg.Position = new Vector3(m_host.AbsolutePosition);
3093 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3374 msg.RegionID = World.RegionInfo.RegionID.Guid;
3094 msg.binaryBucket 3375 msg.binaryBucket
3095 = Util.StringToBytes256( 3376 = Util.StringToBytes256(
3096 "{0}/{1}/{2}/{3}", 3377 "{0}/{1}/{2}/{3}",
@@ -3118,7 +3399,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3118 } 3399 }
3119 3400
3120 emailModule.SendEmail(m_host.UUID, address, subject, message); 3401 emailModule.SendEmail(m_host.UUID, address, subject, message);
3121 llSleep(EMAIL_PAUSE_TIME); 3402 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3122 } 3403 }
3123 3404
3124 public void llGetNextEmail(string address, string subject) 3405 public void llGetNextEmail(string address, string subject)
@@ -3362,15 +3643,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3362 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3643 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3363 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3644 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3364 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3645 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3646 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3365 ScriptBaseClass.PERMISSION_ATTACH; 3647 ScriptBaseClass.PERMISSION_ATTACH;
3366 3648
3367 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3649 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3368 { 3650 {
3369 lock (m_host.TaskInventory) 3651 m_host.TaskInventory.LockItemsForWrite(true);
3370 { 3652 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3371 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3653 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3372 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3654 m_host.TaskInventory.LockItemsForWrite(false);
3373 }
3374 3655
3375 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3656 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3376 "run_time_permissions", new Object[] { 3657 "run_time_permissions", new Object[] {
@@ -3380,28 +3661,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3380 return; 3661 return;
3381 } 3662 }
3382 } 3663 }
3383 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3664 else
3384 { 3665 {
3385 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3666 bool sitting = false;
3386 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3667 if (m_host.SitTargetAvatar == agentID)
3387 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3668 {
3388 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3669 sitting = true;
3389 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3670 }
3671 else
3672 {
3673 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3674 {
3675 if (p.SitTargetAvatar == agentID)
3676 sitting = true;
3677 }
3678 }
3390 3679
3391 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3680 if (sitting)
3392 { 3681 {
3393 lock (m_host.TaskInventory) 3682 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3683 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3684 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3685 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3686 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3687
3688 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3394 { 3689 {
3690 m_host.TaskInventory.LockItemsForWrite(true);
3395 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3691 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3396 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3692 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3397 } 3693 m_host.TaskInventory.LockItemsForWrite(false);
3398 3694
3399 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3695 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3400 "run_time_permissions", new Object[] { 3696 "run_time_permissions", new Object[] {
3401 new LSL_Integer(perm) }, 3697 new LSL_Integer(perm) },
3402 new DetectParams[0])); 3698 new DetectParams[0]));
3403 3699
3404 return; 3700 return;
3701 }
3405 } 3702 }
3406 } 3703 }
3407 3704
@@ -3438,11 +3735,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 3735
3439 if (!m_waitingForScriptAnswer) 3736 if (!m_waitingForScriptAnswer)
3440 { 3737 {
3441 lock (m_host.TaskInventory) 3738 m_host.TaskInventory.LockItemsForWrite(true);
3442 { 3739 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3443 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3740 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3444 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3741 m_host.TaskInventory.LockItemsForWrite(false);
3445 }
3446 3742
3447 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3743 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3448 m_waitingForScriptAnswer=true; 3744 m_waitingForScriptAnswer=true;
@@ -3471,14 +3767,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3767 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3472 llReleaseControls(); 3768 llReleaseControls();
3473 3769
3474 lock (m_host.TaskInventory) 3770 m_host.TaskInventory.LockItemsForWrite(true);
3475 { 3771 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3476 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3772 m_host.TaskInventory.LockItemsForWrite(false);
3477 } 3773
3478 3774 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3479 m_ScriptEngine.PostScriptEvent( 3775 "run_time_permissions", new Object[] {
3480 m_item.ItemID, 3776 new LSL_Integer(answer) },
3481 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3777 new DetectParams[0]));
3482 } 3778 }
3483 3779
3484 public LSL_String llGetPermissionsKey() 3780 public LSL_String llGetPermissionsKey()
@@ -3517,14 +3813,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3813 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3518 { 3814 {
3519 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3815 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3520 3816 if (parts.Count > 0)
3521 foreach (SceneObjectPart part in parts) 3817 {
3522 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3818 try
3819 {
3820 parts[0].ParentGroup.areUpdatesSuspended = true;
3821 foreach (SceneObjectPart part in parts)
3822 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3823 }
3824 finally
3825 {
3826 parts[0].ParentGroup.areUpdatesSuspended = false;
3827 }
3828 }
3523 } 3829 }
3524 3830
3525 public void llCreateLink(string target, int parent) 3831 public void llCreateLink(string target, int parent)
3526 { 3832 {
3527 m_host.AddScriptLPS(1); 3833 m_host.AddScriptLPS(1);
3834
3528 UUID targetID; 3835 UUID targetID;
3529 3836
3530 if (!UUID.TryParse(target, out targetID)) 3837 if (!UUID.TryParse(target, out targetID))
@@ -3630,10 +3937,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3630 // Restructuring Multiple Prims. 3937 // Restructuring Multiple Prims.
3631 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3938 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3632 parts.Remove(parentPrim.RootPart); 3939 parts.Remove(parentPrim.RootPart);
3633 foreach (SceneObjectPart part in parts) 3940 if (parts.Count > 0)
3634 { 3941 {
3635 parentPrim.DelinkFromGroup(part.LocalId, true); 3942 try
3943 {
3944 parts[0].ParentGroup.areUpdatesSuspended = true;
3945 foreach (SceneObjectPart part in parts)
3946 {
3947 parentPrim.DelinkFromGroup(part.LocalId, true);
3948 }
3949 }
3950 finally
3951 {
3952 parts[0].ParentGroup.areUpdatesSuspended = false;
3953 }
3636 } 3954 }
3955
3637 parentPrim.HasGroupChanged = true; 3956 parentPrim.HasGroupChanged = true;
3638 parentPrim.ScheduleGroupForFullUpdate(); 3957 parentPrim.ScheduleGroupForFullUpdate();
3639 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3958 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3642,12 +3961,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3642 { 3961 {
3643 SceneObjectPart newRoot = parts[0]; 3962 SceneObjectPart newRoot = parts[0];
3644 parts.Remove(newRoot); 3963 parts.Remove(newRoot);
3645 foreach (SceneObjectPart part in parts) 3964
3965 try
3646 { 3966 {
3647 // Required for linking 3967 parts[0].ParentGroup.areUpdatesSuspended = true;
3648 part.ClearUpdateSchedule(); 3968 foreach (SceneObjectPart part in parts)
3649 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3969 {
3970 part.ClearUpdateSchedule();
3971 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3972 }
3650 } 3973 }
3974 finally
3975 {
3976 parts[0].ParentGroup.areUpdatesSuspended = false;
3977 }
3978
3979
3651 newRoot.ParentGroup.HasGroupChanged = true; 3980 newRoot.ParentGroup.HasGroupChanged = true;
3652 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3981 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3653 } 3982 }
@@ -3667,6 +3996,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3667 public void llBreakAllLinks() 3996 public void llBreakAllLinks()
3668 { 3997 {
3669 m_host.AddScriptLPS(1); 3998 m_host.AddScriptLPS(1);
3999
4000 TaskInventoryItem item = m_item;
4001
4002 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4003 && !m_automaticLinkPermission)
4004 {
4005 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4006 return;
4007 }
4008
3670 SceneObjectGroup parentPrim = m_host.ParentGroup; 4009 SceneObjectGroup parentPrim = m_host.ParentGroup;
3671 if (parentPrim.AttachmentPoint != 0) 4010 if (parentPrim.AttachmentPoint != 0)
3672 return; // Fail silently if attached 4011 return; // Fail silently if attached
@@ -3686,25 +4025,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 public LSL_String llGetLinkKey(int linknum) 4025 public LSL_String llGetLinkKey(int linknum)
3687 { 4026 {
3688 m_host.AddScriptLPS(1); 4027 m_host.AddScriptLPS(1);
3689 List<UUID> keytable = new List<UUID>();
3690 // parse for sitting avatare-uuids
3691 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3692 {
3693 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3694 keytable.Add(presence.UUID);
3695 });
3696
3697 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3698 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3699 {
3700 return keytable[totalprims - linknum].ToString();
3701 }
3702
3703 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3704 {
3705 return m_host.UUID.ToString();
3706 }
3707
3708 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4028 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3709 if (part != null) 4029 if (part != null)
3710 { 4030 {
@@ -3712,6 +4032,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3712 } 4032 }
3713 else 4033 else
3714 { 4034 {
4035 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4036 {
4037 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4038
4039 if (linknum < 0)
4040 return UUID.Zero.ToString();
4041
4042 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4043 if (avatars.Count > linknum)
4044 {
4045 return avatars[linknum].UUID.ToString();
4046 }
4047 }
3715 return UUID.Zero.ToString(); 4048 return UUID.Zero.ToString();
3716 } 4049 }
3717 } 4050 }
@@ -3811,17 +4144,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3811 m_host.AddScriptLPS(1); 4144 m_host.AddScriptLPS(1);
3812 int count = 0; 4145 int count = 0;
3813 4146
3814 lock (m_host.TaskInventory) 4147 m_host.TaskInventory.LockItemsForRead(true);
4148 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3815 { 4149 {
3816 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4150 if (inv.Value.Type == type || type == -1)
3817 { 4151 {
3818 if (inv.Value.Type == type || type == -1) 4152 count = count + 1;
3819 {
3820 count = count + 1;
3821 }
3822 } 4153 }
3823 } 4154 }
3824 4155
4156 m_host.TaskInventory.LockItemsForRead(false);
3825 return count; 4157 return count;
3826 } 4158 }
3827 4159
@@ -3830,16 +4162,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3830 m_host.AddScriptLPS(1); 4162 m_host.AddScriptLPS(1);
3831 ArrayList keys = new ArrayList(); 4163 ArrayList keys = new ArrayList();
3832 4164
3833 lock (m_host.TaskInventory) 4165 m_host.TaskInventory.LockItemsForRead(true);
4166 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3834 { 4167 {
3835 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4168 if (inv.Value.Type == type || type == -1)
3836 { 4169 {
3837 if (inv.Value.Type == type || type == -1) 4170 keys.Add(inv.Value.Name);
3838 {
3839 keys.Add(inv.Value.Name);
3840 }
3841 } 4171 }
3842 } 4172 }
4173 m_host.TaskInventory.LockItemsForRead(false);
3843 4174
3844 if (keys.Count == 0) 4175 if (keys.Count == 0)
3845 { 4176 {
@@ -3876,25 +4207,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3876 } 4207 }
3877 4208
3878 // move the first object found with this inventory name 4209 // move the first object found with this inventory name
3879 lock (m_host.TaskInventory) 4210 m_host.TaskInventory.LockItemsForRead(true);
4211 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3880 { 4212 {
3881 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4213 if (inv.Value.Name == inventory)
3882 { 4214 {
3883 if (inv.Value.Name == inventory) 4215 found = true;
3884 { 4216 objId = inv.Key;
3885 found = true; 4217 assetType = inv.Value.Type;
3886 objId = inv.Key; 4218 objName = inv.Value.Name;
3887 assetType = inv.Value.Type; 4219 break;
3888 objName = inv.Value.Name;
3889 break;
3890 }
3891 } 4220 }
3892 } 4221 }
4222 m_host.TaskInventory.LockItemsForRead(false);
3893 4223
3894 if (!found) 4224 if (!found)
3895 { 4225 {
3896 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4226 llSay(0, String.Format("Could not find object '{0}'", inventory));
3897 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4227 return;
4228// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3898 } 4229 }
3899 4230
3900 // check if destination is an object 4231 // check if destination is an object
@@ -3920,48 +4251,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3920 return; 4251 return;
3921 } 4252 }
3922 } 4253 }
4254
3923 // destination is an avatar 4255 // destination is an avatar
3924 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4256 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3925 4257
3926 if (agentItem == null) 4258 if (agentItem == null)
3927 return; 4259 return;
3928 4260
3929 byte[] bucket = new byte[17]; 4261 byte[] bucket = new byte[1];
3930 bucket[0] = (byte)assetType; 4262 bucket[0] = (byte)assetType;
3931 byte[] objBytes = agentItem.ID.GetBytes(); 4263 //byte[] objBytes = agentItem.ID.GetBytes();
3932 Array.Copy(objBytes, 0, bucket, 1, 16); 4264 //Array.Copy(objBytes, 0, bucket, 1, 16);
3933 4265
3934 GridInstantMessage msg = new GridInstantMessage(World, 4266 GridInstantMessage msg = new GridInstantMessage(World,
3935 m_host.UUID, m_host.Name+", an object owned by "+ 4267 m_host.OwnerID, m_host.Name, destId,
3936 resolveName(m_host.OwnerID)+",", destId,
3937 (byte)InstantMessageDialog.TaskInventoryOffered, 4268 (byte)InstantMessageDialog.TaskInventoryOffered,
3938 false, objName+"\n"+m_host.Name+" is located at "+ 4269 false, objName+". "+m_host.Name+" is located at "+
3939 World.RegionInfo.RegionName+" "+ 4270 World.RegionInfo.RegionName+" "+
3940 m_host.AbsolutePosition.ToString(), 4271 m_host.AbsolutePosition.ToString(),
3941 agentItem.ID, true, m_host.AbsolutePosition, 4272 agentItem.ID, true, m_host.AbsolutePosition,
3942 bucket); 4273 bucket);
3943 if (m_TransferModule != null) 4274
3944 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4275 ScenePresence sp;
4276
4277 if (World.TryGetScenePresence(destId, out sp))
4278 {
4279 sp.ControllingClient.SendInstantMessage(msg);
4280 }
4281 else
4282 {
4283 if (m_TransferModule != null)
4284 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4285 }
4286
4287 //This delay should only occur when giving inventory to avatars.
3945 ScriptSleep(3000); 4288 ScriptSleep(3000);
3946 } 4289 }
3947 } 4290 }
3948 4291
4292 [DebuggerNonUserCode]
3949 public void llRemoveInventory(string name) 4293 public void llRemoveInventory(string name)
3950 { 4294 {
3951 m_host.AddScriptLPS(1); 4295 m_host.AddScriptLPS(1);
3952 4296
3953 lock (m_host.TaskInventory) 4297 List<TaskInventoryItem> inv;
4298 try
3954 { 4299 {
3955 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4300 m_host.TaskInventory.LockItemsForRead(true);
4301 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4302 }
4303 finally
4304 {
4305 m_host.TaskInventory.LockItemsForRead(false);
4306 }
4307 foreach (TaskInventoryItem item in inv)
4308 {
4309 if (item.Name == name)
3956 { 4310 {
3957 if (item.Name == name) 4311 if (item.ItemID == m_item.ItemID)
3958 { 4312 throw new ScriptDeleteException();
3959 if (item.ItemID == m_item.ItemID) 4313 else
3960 throw new ScriptDeleteException(); 4314 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3961 else 4315 return;
3962 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3963 return;
3964 }
3965 } 4316 }
3966 } 4317 }
3967 } 4318 }
@@ -3996,115 +4347,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3996 { 4347 {
3997 m_host.AddScriptLPS(1); 4348 m_host.AddScriptLPS(1);
3998 4349
3999 UUID uuid = (UUID)id; 4350 UUID uuid;
4000 PresenceInfo pinfo = null; 4351 if (UUID.TryParse(id, out uuid))
4001 UserAccount account;
4002
4003 UserInfoCacheEntry ce;
4004 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4005 { 4352 {
4006 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4353 PresenceInfo pinfo = null;
4007 if (account == null) 4354 UserAccount account;
4355
4356 UserInfoCacheEntry ce;
4357 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4008 { 4358 {
4009 m_userInfoCache[uuid] = null; // Cache negative 4359 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4010 return UUID.Zero.ToString(); 4360 if (account == null)
4011 } 4361 {
4362 m_userInfoCache[uuid] = null; // Cache negative
4363 return UUID.Zero.ToString();
4364 }
4012 4365
4013 4366
4014 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4367 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4015 if (pinfos != null && pinfos.Length > 0) 4368 if (pinfos != null && pinfos.Length > 0)
4016 {
4017 foreach (PresenceInfo p in pinfos)
4018 { 4369 {
4019 if (p.RegionID != UUID.Zero) 4370 foreach (PresenceInfo p in pinfos)
4020 { 4371 {
4021 pinfo = p; 4372 if (p.RegionID != UUID.Zero)
4373 {
4374 pinfo = p;
4375 }
4022 } 4376 }
4023 } 4377 }
4024 }
4025 4378
4026 ce = new UserInfoCacheEntry(); 4379 ce = new UserInfoCacheEntry();
4027 ce.time = Util.EnvironmentTickCount(); 4380 ce.time = Util.EnvironmentTickCount();
4028 ce.account = account; 4381 ce.account = account;
4029 ce.pinfo = pinfo; 4382 ce.pinfo = pinfo;
4030 } 4383 m_userInfoCache[uuid] = ce;
4031 else 4384 }
4032 { 4385 else
4033 if (ce == null) 4386 {
4034 return UUID.Zero.ToString(); 4387 if (ce == null)
4388 return UUID.Zero.ToString();
4035 4389
4036 account = ce.account; 4390 account = ce.account;
4037 pinfo = ce.pinfo; 4391 pinfo = ce.pinfo;
4038 } 4392 }
4039 4393
4040 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4394 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4041 {
4042 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4043 if (pinfos != null && pinfos.Length > 0)
4044 { 4395 {
4045 foreach (PresenceInfo p in pinfos) 4396 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4397 if (pinfos != null && pinfos.Length > 0)
4046 { 4398 {
4047 if (p.RegionID != UUID.Zero) 4399 foreach (PresenceInfo p in pinfos)
4048 { 4400 {
4049 pinfo = p; 4401 if (p.RegionID != UUID.Zero)
4402 {
4403 pinfo = p;
4404 }
4050 } 4405 }
4051 } 4406 }
4052 } 4407 else
4053 else 4408 pinfo = null;
4054 pinfo = null;
4055 4409
4056 ce.time = Util.EnvironmentTickCount(); 4410 ce.time = Util.EnvironmentTickCount();
4057 ce.pinfo = pinfo; 4411 ce.pinfo = pinfo;
4058 } 4412 }
4059 4413
4060 string reply = String.Empty; 4414 string reply = String.Empty;
4061 4415
4062 switch (data) 4416 switch (data)
4063 { 4417 {
4064 case 1: // DATA_ONLINE (0|1) 4418 case 1: // DATA_ONLINE (0|1)
4065 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4419 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4066 reply = "1"; 4420 reply = "1";
4067 else 4421 else
4068 reply = "0"; 4422 reply = "0";
4069 break; 4423 break;
4070 case 2: // DATA_NAME (First Last) 4424 case 2: // DATA_NAME (First Last)
4071 reply = account.FirstName + " " + account.LastName; 4425 reply = account.FirstName + " " + account.LastName;
4072 break; 4426 break;
4073 case 3: // DATA_BORN (YYYY-MM-DD) 4427 case 3: // DATA_BORN (YYYY-MM-DD)
4074 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4428 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4075 born = born.AddSeconds(account.Created); 4429 born = born.AddSeconds(account.Created);
4076 reply = born.ToString("yyyy-MM-dd"); 4430 reply = born.ToString("yyyy-MM-dd");
4077 break; 4431 break;
4078 case 4: // DATA_RATING (0,0,0,0,0,0) 4432 case 4: // DATA_RATING (0,0,0,0,0,0)
4079 reply = "0,0,0,0,0,0"; 4433 reply = "0,0,0,0,0,0";
4080 break; 4434 break;
4081 case 7: // DATA_USERLEVEL (integer) 4435 case 8: // DATA_PAYINFO (0|1|2|3)
4082 reply = account.UserLevel.ToString(); 4436 reply = "0";
4083 break; 4437 break;
4084 case 8: // DATA_PAYINFO (0|1|2|3) 4438 default:
4085 reply = "0"; 4439 return UUID.Zero.ToString(); // Raise no event
4086 break; 4440 }
4087 default:
4088 return UUID.Zero.ToString(); // Raise no event
4089 }
4090 4441
4091 UUID rq = UUID.Random(); 4442 UUID rq = UUID.Random();
4092 4443
4093 UUID tid = AsyncCommands. 4444 UUID tid = AsyncCommands.
4094 DataserverPlugin.RegisterRequest(m_host.LocalId, 4445 DataserverPlugin.RegisterRequest(m_host.LocalId,
4095 m_item.ItemID, rq.ToString()); 4446 m_item.ItemID, rq.ToString());
4096 4447
4097 AsyncCommands. 4448 AsyncCommands.
4098 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4449 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4099 4450
4100 ScriptSleep(100); 4451 ScriptSleep(100);
4101 return tid.ToString(); 4452 return tid.ToString();
4453 }
4454 else
4455 {
4456 ShoutError("Invalid UUID passed to llRequestAgentData.");
4457 }
4458 return "";
4102 } 4459 }
4103 4460
4104 public LSL_String llRequestInventoryData(string name) 4461 public LSL_String llRequestInventoryData(string name)
4105 { 4462 {
4106 m_host.AddScriptLPS(1); 4463 m_host.AddScriptLPS(1);
4107 4464
4465 //Clone is thread safe
4108 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4466 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4109 4467
4110 foreach (TaskInventoryItem item in itemDictionary.Values) 4468 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4156,19 +4514,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4156 if (UUID.TryParse(agent, out agentId)) 4514 if (UUID.TryParse(agent, out agentId))
4157 { 4515 {
4158 ScenePresence presence = World.GetScenePresence(agentId); 4516 ScenePresence presence = World.GetScenePresence(agentId);
4159 if (presence != null) 4517 if (presence != null && presence.PresenceType != PresenceType.Npc)
4160 { 4518 {
4519 // agent must not be a god
4520 if (presence.UserLevel >= 200) return;
4521
4161 // agent must be over the owners land 4522 // agent must be over the owners land
4162 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4523 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4163 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4524 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4164 { 4525 {
4165 World.TeleportClientHome(agentId, presence.ControllingClient); 4526 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4527 {
4528 // They can't be teleported home for some reason
4529 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4530 if (regionInfo != null)
4531 {
4532 World.RequestTeleportLocation(
4533 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4534 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4535 }
4536 }
4166 } 4537 }
4167 } 4538 }
4168 } 4539 }
4169 ScriptSleep(5000); 4540 ScriptSleep(5000);
4170 } 4541 }
4171 4542
4543 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4544 {
4545 m_host.AddScriptLPS(1);
4546 UUID agentId = new UUID();
4547 if (UUID.TryParse(agent, out agentId))
4548 {
4549 ScenePresence presence = World.GetScenePresence(agentId);
4550 if (presence != null && presence.PresenceType != PresenceType.Npc)
4551 {
4552 // agent must not be a god
4553 if (presence.GodLevel >= 200) return;
4554
4555 if (simname == String.Empty)
4556 simname = World.RegionInfo.RegionName;
4557
4558 // agent must be over the owners land
4559 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4560 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4561 {
4562 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4563 }
4564 else // or must be wearing the prim
4565 {
4566 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4567 {
4568 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4569 }
4570 }
4571 }
4572 }
4573 }
4574
4172 public void llTextBox(string agent, string message, int chatChannel) 4575 public void llTextBox(string agent, string message, int chatChannel)
4173 { 4576 {
4174 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4577 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4180,7 +4583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4180 UUID av = new UUID(); 4583 UUID av = new UUID();
4181 if (!UUID.TryParse(agent,out av)) 4584 if (!UUID.TryParse(agent,out av))
4182 { 4585 {
4183 LSLError("First parameter to llDialog needs to be a key"); 4586 //LSLError("First parameter to llDialog needs to be a key");
4184 return; 4587 return;
4185 } 4588 }
4186 4589
@@ -4212,25 +4615,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4212 public void llCollisionSound(string impact_sound, double impact_volume) 4615 public void llCollisionSound(string impact_sound, double impact_volume)
4213 { 4616 {
4214 m_host.AddScriptLPS(1); 4617 m_host.AddScriptLPS(1);
4215 4618
4619 if(impact_sound == "")
4620 {
4621 m_host.CollisionSoundVolume = (float)impact_volume;
4622 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4623 return;
4624 }
4216 // TODO: Parameter check logic required. 4625 // TODO: Parameter check logic required.
4217 UUID soundId = UUID.Zero; 4626 UUID soundId = UUID.Zero;
4218 if (!UUID.TryParse(impact_sound, out soundId)) 4627 if (!UUID.TryParse(impact_sound, out soundId))
4219 { 4628 {
4220 lock (m_host.TaskInventory) 4629 m_host.TaskInventory.LockItemsForRead(true);
4630 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4221 { 4631 {
4222 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4632 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4223 { 4633 {
4224 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4634 soundId = item.AssetID;
4225 { 4635 break;
4226 soundId = item.AssetID;
4227 break;
4228 }
4229 } 4636 }
4230 } 4637 }
4638 m_host.TaskInventory.LockItemsForRead(false);
4231 } 4639 }
4232 m_host.CollisionSound = soundId;
4233 m_host.CollisionSoundVolume = (float)impact_volume; 4640 m_host.CollisionSoundVolume = (float)impact_volume;
4641 m_host.CollisionSound = soundId;
4234 } 4642 }
4235 4643
4236 public LSL_String llGetAnimation(string id) 4644 public LSL_String llGetAnimation(string id)
@@ -4267,6 +4675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4267 UUID partItemID; 4675 UUID partItemID;
4268 foreach (SceneObjectPart part in parts) 4676 foreach (SceneObjectPart part in parts)
4269 { 4677 {
4678 //Clone is thread safe
4270 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4679 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4271 4680
4272 foreach (TaskInventoryItem item in itemsDictionary.Values) 4681 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4400,7 +4809,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4400 { 4809 {
4401 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4810 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4402 float distance_term = distance * distance * distance; // Script Energy 4811 float distance_term = distance * distance * distance; // Script Energy
4403 float pusher_mass = m_host.GetMass(); 4812 // use total object mass and not part
4813 float pusher_mass = m_host.ParentGroup.GetMass();
4404 4814
4405 float PUSH_ATTENUATION_DISTANCE = 17f; 4815 float PUSH_ATTENUATION_DISTANCE = 17f;
4406 float PUSH_ATTENUATION_SCALE = 5f; 4816 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4639,23 +5049,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4639 { 5049 {
4640 m_host.AddScriptLPS(1); 5050 m_host.AddScriptLPS(1);
4641 5051
4642 lock (m_host.TaskInventory) 5052 m_host.TaskInventory.LockItemsForRead(true);
5053 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4643 { 5054 {
4644 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5055 if (inv.Value.Name == name)
4645 { 5056 {
4646 if (inv.Value.Name == name) 5057 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4647 { 5058 {
4648 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5059 m_host.TaskInventory.LockItemsForRead(false);
4649 { 5060 return inv.Value.AssetID.ToString();
4650 return inv.Value.AssetID.ToString(); 5061 }
4651 } 5062 else
4652 else 5063 {
4653 { 5064 m_host.TaskInventory.LockItemsForRead(false);
4654 return UUID.Zero.ToString(); 5065 return UUID.Zero.ToString();
4655 }
4656 } 5066 }
4657 } 5067 }
4658 } 5068 }
5069 m_host.TaskInventory.LockItemsForRead(false);
4659 5070
4660 return UUID.Zero.ToString(); 5071 return UUID.Zero.ToString();
4661 } 5072 }
@@ -4789,7 +5200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4789 public LSL_Vector llGetCenterOfMass() 5200 public LSL_Vector llGetCenterOfMass()
4790 { 5201 {
4791 m_host.AddScriptLPS(1); 5202 m_host.AddScriptLPS(1);
4792 Vector3 center = m_host.GetGeometricCenter(); 5203 Vector3 center = m_host.GetCenterOfMass();
4793 return new LSL_Vector(center.X,center.Y,center.Z); 5204 return new LSL_Vector(center.X,center.Y,center.Z);
4794 } 5205 }
4795 5206
@@ -4808,14 +5219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4808 { 5219 {
4809 m_host.AddScriptLPS(1); 5220 m_host.AddScriptLPS(1);
4810 5221
4811 if (src == null) 5222 return src.Length;
4812 {
4813 return 0;
4814 }
4815 else
4816 {
4817 return src.Length;
4818 }
4819 } 5223 }
4820 5224
4821 public LSL_Integer llList2Integer(LSL_List src, int index) 5225 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4861,7 +5265,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4861 else if (src.Data[index] is LSL_Float) 5265 else if (src.Data[index] is LSL_Float)
4862 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5266 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4863 else if (src.Data[index] is LSL_String) 5267 else if (src.Data[index] is LSL_String)
4864 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5268 {
5269 string str = ((LSL_String) src.Data[index]).m_string;
5270 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5271 if (m != Match.Empty)
5272 {
5273 str = m.Value;
5274 double d = 0.0;
5275 if (!Double.TryParse(str, out d))
5276 return 0.0;
5277
5278 return d;
5279 }
5280 return 0.0;
5281 }
4865 return Convert.ToDouble(src.Data[index]); 5282 return Convert.ToDouble(src.Data[index]);
4866 } 5283 }
4867 catch (FormatException) 5284 catch (FormatException)
@@ -5134,7 +5551,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5134 } 5551 }
5135 } 5552 }
5136 } 5553 }
5137 else { 5554 else
5555 {
5138 object[] array = new object[src.Length]; 5556 object[] array = new object[src.Length];
5139 Array.Copy(src.Data, 0, array, 0, src.Length); 5557 Array.Copy(src.Data, 0, array, 0, src.Length);
5140 result = new LSL_List(array); 5558 result = new LSL_List(array);
@@ -5241,7 +5659,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5241 public LSL_Integer llGetRegionAgentCount() 5659 public LSL_Integer llGetRegionAgentCount()
5242 { 5660 {
5243 m_host.AddScriptLPS(1); 5661 m_host.AddScriptLPS(1);
5244 return new LSL_Integer(World.GetRootAgentCount()); 5662
5663 int count = 0;
5664 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5665 count++;
5666 });
5667
5668 return new LSL_Integer(count);
5245 } 5669 }
5246 5670
5247 public LSL_Vector llGetRegionCorner() 5671 public LSL_Vector llGetRegionCorner()
@@ -5521,6 +5945,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5521 flags |= ScriptBaseClass.AGENT_SITTING; 5945 flags |= ScriptBaseClass.AGENT_SITTING;
5522 } 5946 }
5523 5947
5948 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
5949 {
5950 flags |= ScriptBaseClass.AGENT_MALE;
5951 }
5952
5524 return flags; 5953 return flags;
5525 } 5954 }
5526 5955
@@ -5668,10 +6097,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5668 m_host.AddScriptLPS(1); 6097 m_host.AddScriptLPS(1);
5669 6098
5670 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6099 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5671 6100 if (parts.Count > 0)
5672 foreach (var part in parts)
5673 { 6101 {
5674 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6102 try
6103 {
6104 parts[0].ParentGroup.areUpdatesSuspended = true;
6105 foreach (var part in parts)
6106 {
6107 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6108 }
6109 }
6110 finally
6111 {
6112 parts[0].ParentGroup.areUpdatesSuspended = false;
6113 }
5675 } 6114 }
5676 } 6115 }
5677 6116
@@ -5723,13 +6162,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5723 6162
5724 if (m_host.OwnerID == land.LandData.OwnerID) 6163 if (m_host.OwnerID == land.LandData.OwnerID)
5725 { 6164 {
5726 World.TeleportClientHome(agentID, presence.ControllingClient); 6165 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6166 presence.TeleportWithMomentum(pos, null);
6167 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5727 } 6168 }
5728 } 6169 }
5729 } 6170 }
5730 ScriptSleep(5000); 6171 ScriptSleep(5000);
5731 } 6172 }
5732 6173
6174 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6175 {
6176 return ParseString2List(str, separators, in_spacers, false);
6177 }
6178
5733 public LSL_Integer llOverMyLand(string id) 6179 public LSL_Integer llOverMyLand(string id)
5734 { 6180 {
5735 m_host.AddScriptLPS(1); 6181 m_host.AddScriptLPS(1);
@@ -5794,8 +6240,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5794 UUID agentId = new UUID(); 6240 UUID agentId = new UUID();
5795 if (!UUID.TryParse(agent, out agentId)) 6241 if (!UUID.TryParse(agent, out agentId))
5796 return new LSL_Integer(0); 6242 return new LSL_Integer(0);
6243 if (agentId == m_host.GroupID)
6244 return new LSL_Integer(1);
5797 ScenePresence presence = World.GetScenePresence(agentId); 6245 ScenePresence presence = World.GetScenePresence(agentId);
5798 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6246 if (presence == null || presence.IsChildAgent) // Return false for child agents
5799 return new LSL_Integer(0); 6247 return new LSL_Integer(0);
5800 IClientAPI client = presence.ControllingClient; 6248 IClientAPI client = presence.ControllingClient;
5801 if (m_host.GroupID == client.ActiveGroupId) 6249 if (m_host.GroupID == client.ActiveGroupId)
@@ -5930,7 +6378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5930 return m_host.ParentGroup.AttachmentPoint; 6378 return m_host.ParentGroup.AttachmentPoint;
5931 } 6379 }
5932 6380
5933 public LSL_Integer llGetFreeMemory() 6381 public virtual LSL_Integer llGetFreeMemory()
5934 { 6382 {
5935 m_host.AddScriptLPS(1); 6383 m_host.AddScriptLPS(1);
5936 // Make scripts designed for LSO happy 6384 // Make scripts designed for LSO happy
@@ -6047,7 +6495,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6047 SetParticleSystem(m_host, rules); 6495 SetParticleSystem(m_host, rules);
6048 } 6496 }
6049 6497
6050 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6498 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6499 {
6051 6500
6052 6501
6053 if (rules.Length == 0) 6502 if (rules.Length == 0)
@@ -6241,14 +6690,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6241 6690
6242 protected UUID GetTaskInventoryItem(string name) 6691 protected UUID GetTaskInventoryItem(string name)
6243 { 6692 {
6244 lock (m_host.TaskInventory) 6693 m_host.TaskInventory.LockItemsForRead(true);
6694 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6245 { 6695 {
6246 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6696 if (inv.Value.Name == name)
6247 { 6697 {
6248 if (inv.Value.Name == name) 6698 m_host.TaskInventory.LockItemsForRead(false);
6249 return inv.Key; 6699 return inv.Key;
6250 } 6700 }
6251 } 6701 }
6702 m_host.TaskInventory.LockItemsForRead(false);
6252 6703
6253 return UUID.Zero; 6704 return UUID.Zero;
6254 } 6705 }
@@ -6286,16 +6737,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6286 if (folderID == UUID.Zero) 6737 if (folderID == UUID.Zero)
6287 return; 6738 return;
6288 6739
6289 byte[] bucket = new byte[17]; 6740 byte[] bucket = new byte[1];
6290 bucket[0] = (byte)AssetType.Folder; 6741 bucket[0] = (byte)AssetType.Folder;
6291 byte[] objBytes = folderID.GetBytes(); 6742 //byte[] objBytes = folderID.GetBytes();
6292 Array.Copy(objBytes, 0, bucket, 1, 16); 6743 //Array.Copy(objBytes, 0, bucket, 1, 16);
6293 6744
6294 GridInstantMessage msg = new GridInstantMessage(World, 6745 GridInstantMessage msg = new GridInstantMessage(World,
6295 m_host.UUID, m_host.Name+", an object owned by "+ 6746 m_host.OwnerID, m_host.Name, destID,
6296 resolveName(m_host.OwnerID)+",", destID, 6747 (byte)InstantMessageDialog.TaskInventoryOffered,
6297 (byte)InstantMessageDialog.InventoryOffered, 6748 false, category+". "+m_host.Name+" is located at "+
6298 false, category+"\n"+m_host.Name+" is located at "+
6299 World.RegionInfo.RegionName+" "+ 6749 World.RegionInfo.RegionName+" "+
6300 m_host.AbsolutePosition.ToString(), 6750 m_host.AbsolutePosition.ToString(),
6301 folderID, true, m_host.AbsolutePosition, 6751 folderID, true, m_host.AbsolutePosition,
@@ -6533,13 +6983,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6533 UUID av = new UUID(); 6983 UUID av = new UUID();
6534 if (!UUID.TryParse(avatar,out av)) 6984 if (!UUID.TryParse(avatar,out av))
6535 { 6985 {
6536 LSLError("First parameter to llDialog needs to be a key"); 6986 //LSLError("First parameter to llDialog needs to be a key");
6537 return; 6987 return;
6538 } 6988 }
6539 if (buttons.Length < 1) 6989 if (buttons.Length < 1)
6540 { 6990 {
6541 LSLError("No less than 1 button can be shown"); 6991 buttons.Add("OK");
6542 return;
6543 } 6992 }
6544 if (buttons.Length > 12) 6993 if (buttons.Length > 12)
6545 { 6994 {
@@ -6556,7 +7005,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6556 } 7005 }
6557 if (buttons.Data[i].ToString().Length > 24) 7006 if (buttons.Data[i].ToString().Length > 24)
6558 { 7007 {
6559 LSLError("button label cannot be longer than 24 characters"); 7008 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6560 return; 7009 return;
6561 } 7010 }
6562 buts[i] = buttons.Data[i].ToString(); 7011 buts[i] = buttons.Data[i].ToString();
@@ -6615,22 +7064,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6615 } 7064 }
6616 7065
6617 // copy the first script found with this inventory name 7066 // copy the first script found with this inventory name
6618 lock (m_host.TaskInventory) 7067 TaskInventoryItem scriptItem = null;
7068 m_host.TaskInventory.LockItemsForRead(true);
7069 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6619 { 7070 {
6620 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7071 if (inv.Value.Name == name)
6621 { 7072 {
6622 if (inv.Value.Name == name) 7073 // make sure the object is a script
7074 if (10 == inv.Value.Type)
6623 { 7075 {
6624 // make sure the object is a script 7076 found = true;
6625 if (10 == inv.Value.Type) 7077 srcId = inv.Key;
6626 { 7078 scriptItem = inv.Value;
6627 found = true; 7079 break;
6628 srcId = inv.Key;
6629 break;
6630 }
6631 } 7080 }
6632 } 7081 }
6633 } 7082 }
7083 m_host.TaskInventory.LockItemsForRead(false);
6634 7084
6635 if (!found) 7085 if (!found)
6636 { 7086 {
@@ -6638,9 +7088,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6638 return; 7088 return;
6639 } 7089 }
6640 7090
6641 // the rest of the permission checks are done in RezScript, so check the pin there as well 7091 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6642 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7092 if (dest != null)
7093 {
7094 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7095 {
7096 // the rest of the permission checks are done in RezScript, so check the pin there as well
7097 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6643 7098
7099 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7100 m_host.Inventory.RemoveInventoryItem(srcId);
7101 }
7102 }
6644 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7103 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6645 ScriptSleep(3000); 7104 ScriptSleep(3000);
6646 } 7105 }
@@ -6703,19 +7162,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6703 public LSL_String llMD5String(string src, int nonce) 7162 public LSL_String llMD5String(string src, int nonce)
6704 { 7163 {
6705 m_host.AddScriptLPS(1); 7164 m_host.AddScriptLPS(1);
6706 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7165 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6707 } 7166 }
6708 7167
6709 public LSL_String llSHA1String(string src) 7168 public LSL_String llSHA1String(string src)
6710 { 7169 {
6711 m_host.AddScriptLPS(1); 7170 m_host.AddScriptLPS(1);
6712 return Util.SHA1Hash(src).ToLower(); 7171 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6713 } 7172 }
6714 7173
6715 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7174 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6716 { 7175 {
6717 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7176 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6718 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7177 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7178 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7179 return shapeBlock;
6719 7180
6720 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7181 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6721 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7182 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6820,6 +7281,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6820 // Prim type box, cylinder and prism. 7281 // Prim type box, cylinder and prism.
6821 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) 7282 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)
6822 { 7283 {
7284 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7285 return;
7286
6823 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7287 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6824 ObjectShapePacket.ObjectDataBlock shapeBlock; 7288 ObjectShapePacket.ObjectDataBlock shapeBlock;
6825 7289
@@ -6873,6 +7337,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6873 // Prim type sphere. 7337 // Prim type sphere.
6874 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7338 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6875 { 7339 {
7340 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7341 return;
7342
6876 ObjectShapePacket.ObjectDataBlock shapeBlock; 7343 ObjectShapePacket.ObjectDataBlock shapeBlock;
6877 7344
6878 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7345 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6914,6 +7381,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6914 // Prim type torus, tube and ring. 7381 // Prim type torus, tube and ring.
6915 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) 7382 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)
6916 { 7383 {
7384 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7385 return;
7386
6917 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7387 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6918 ObjectShapePacket.ObjectDataBlock shapeBlock; 7388 ObjectShapePacket.ObjectDataBlock shapeBlock;
6919 7389
@@ -7049,6 +7519,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7049 // Prim type sculpt. 7519 // Prim type sculpt.
7050 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7520 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7051 { 7521 {
7522 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7523 return;
7524
7052 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7525 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7053 UUID sculptId; 7526 UUID sculptId;
7054 7527
@@ -7073,7 +7546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7073 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7546 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7074 { 7547 {
7075 // default 7548 // default
7076 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7549 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7077 } 7550 }
7078 7551
7079 part.Shape.SetSculptProperties((byte)type, sculptId); 7552 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7089,32 +7562,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7089 ScriptSleep(200); 7562 ScriptSleep(200);
7090 } 7563 }
7091 7564
7092 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7565 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7093 { 7566 {
7094 m_host.AddScriptLPS(1); 7567 m_host.AddScriptLPS(1);
7095 7568
7096 setLinkPrimParams(linknumber, rules); 7569 setLinkPrimParams(linknumber, rules);
7570 }
7097 7571
7098 ScriptSleep(200); 7572 private void setLinkPrimParams(int linknumber, LSL_List rules)
7573 {
7574 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7575 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7576 if (parts.Count>0)
7577 {
7578 try
7579 {
7580 parts[0].ParentGroup.areUpdatesSuspended = true;
7581 foreach (SceneObjectPart part in parts)
7582 SetPrimParams(part, rules);
7583 }
7584 finally
7585 {
7586 parts[0].ParentGroup.areUpdatesSuspended = false;
7587 }
7588 }
7589 if (avatars.Count > 0)
7590 {
7591 foreach (ScenePresence avatar in avatars)
7592 SetPrimParams(avatar, rules);
7593 }
7099 } 7594 }
7100 7595
7101 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7596 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7597 float material_density, float material_friction,
7598 float material_restitution, float material_gravity_modifier)
7102 { 7599 {
7103 m_host.AddScriptLPS(1); 7600 ExtraPhysicsData physdata = new ExtraPhysicsData();
7601 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7602 physdata.Density = part.Density;
7603 physdata.Friction = part.Friction;
7604 physdata.Bounce = part.Bounciness;
7605 physdata.GravitationModifier = part.GravityModifier;
7104 7606
7105 setLinkPrimParams(linknumber, rules); 7607 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7608 physdata.Density = material_density;
7609 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7610 physdata.Friction = material_friction;
7611 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7612 physdata.Bounce = material_restitution;
7613 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7614 physdata.GravitationModifier = material_gravity_modifier;
7615
7616 part.UpdateExtraPhysics(physdata);
7106 } 7617 }
7107 7618
7108 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7619 public void llSetPhysicsMaterial(int material_bits,
7620 float material_gravity_modifier, float material_restitution,
7621 float material_friction, float material_density)
7109 { 7622 {
7110 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7623 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7624 }
7111 7625
7112 foreach (SceneObjectPart part in parts) 7626 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7113 SetPrimParams(part, rules); 7627 {
7628 llSetLinkPrimitiveParamsFast(linknumber, rules);
7629 ScriptSleep(200);
7630 }
7631
7632 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7633 {
7634 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7635 //We only support PRIM_POSITION and PRIM_ROTATION
7636
7637 int idx = 0;
7638
7639 while (idx < rules.Length)
7640 {
7641 int code = rules.GetLSLIntegerItem(idx++);
7642
7643 int remain = rules.Length - idx;
7644
7645 switch (code)
7646 {
7647 case (int)ScriptBaseClass.PRIM_POSITION:
7648 {
7649 if (remain < 1)
7650 return;
7651 LSL_Vector v;
7652 v = rules.GetVector3Item(idx++);
7653
7654 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7655 if (part == null)
7656 break;
7657
7658 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7659 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7660 if (llGetLinkNumber() > 1)
7661 {
7662 localRot = llGetLocalRot();
7663 localPos = llGetLocalPos();
7664 }
7665
7666 v -= localPos;
7667 v /= localRot;
7668
7669 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7670
7671 v = v + 2 * sitOffset;
7672
7673 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7674 av.SendAvatarDataToAllAgents();
7675
7676 }
7677 break;
7678
7679 case (int)ScriptBaseClass.PRIM_ROTATION:
7680 {
7681 if (remain < 1)
7682 return;
7683
7684 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7685 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7686 if (llGetLinkNumber() > 1)
7687 {
7688 localRot = llGetLocalRot();
7689 localPos = llGetLocalPos();
7690 }
7691
7692 LSL_Rotation r;
7693 r = rules.GetQuaternionItem(idx++);
7694 r = r * llGetRootRotation() / localRot;
7695 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7696 av.SendAvatarDataToAllAgents();
7697 }
7698 break;
7699 }
7700 }
7114 } 7701 }
7115 7702
7116 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7703 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7117 { 7704 {
7705 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7706 return;
7707
7118 int idx = 0; 7708 int idx = 0;
7119 7709
7120 bool positionChanged = false; 7710 bool positionChanged = false;
@@ -7436,6 +8026,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7436 part.ScriptSetPhysicsStatus(physics); 8026 part.ScriptSetPhysicsStatus(physics);
7437 break; 8027 break;
7438 8028
8029 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8030 if (remain < 1)
8031 return;
8032
8033 int shape_type = rules.GetLSLIntegerItem(idx++);
8034
8035 ExtraPhysicsData physdata = new ExtraPhysicsData();
8036 physdata.Density = part.Density;
8037 physdata.Bounce = part.Bounciness;
8038 physdata.GravitationModifier = part.GravityModifier;
8039 physdata.PhysShapeType = (PhysShapeType)shape_type;
8040
8041 part.UpdateExtraPhysics(physdata);
8042
8043 break;
8044
8045 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8046 if (remain < 5)
8047 return;
8048
8049 int material_bits = rules.GetLSLIntegerItem(idx++);
8050 float material_density = (float)rules.GetLSLFloatItem(idx++);
8051 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8052 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8053 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8054
8055 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8056
8057 break;
8058
7439 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8059 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7440 if (remain < 1) 8060 if (remain < 1)
7441 return; 8061 return;
@@ -7509,7 +8129,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7509 if (part.ParentGroup.RootPart == part) 8129 if (part.ParentGroup.RootPart == part)
7510 { 8130 {
7511 SceneObjectGroup parent = part.ParentGroup; 8131 SceneObjectGroup parent = part.ParentGroup;
7512 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8132 Util.FireAndForget(delegate(object x) {
8133 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8134 });
7513 } 8135 }
7514 else 8136 else
7515 { 8137 {
@@ -7520,6 +8142,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7520 } 8142 }
7521 } 8143 }
7522 } 8144 }
8145
8146 if (positionChanged)
8147 {
8148 if (part.ParentGroup.RootPart == part)
8149 {
8150 SceneObjectGroup parent = part.ParentGroup;
8151 Util.FireAndForget(delegate(object x) {
8152 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8153 });
8154 }
8155 else
8156 {
8157 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8158 SceneObjectGroup parent = part.ParentGroup;
8159 parent.HasGroupChanged = true;
8160 parent.ScheduleGroupForTerseUpdate();
8161 }
8162 }
7523 } 8163 }
7524 8164
7525 public LSL_String llStringToBase64(string str) 8165 public LSL_String llStringToBase64(string str)
@@ -7680,13 +8320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7680 public LSL_Integer llGetNumberOfPrims() 8320 public LSL_Integer llGetNumberOfPrims()
7681 { 8321 {
7682 m_host.AddScriptLPS(1); 8322 m_host.AddScriptLPS(1);
7683 int avatarCount = 0; 8323 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7684 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8324
7685 {
7686 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7687 avatarCount++;
7688 });
7689
7690 return m_host.ParentGroup.PrimCount + avatarCount; 8325 return m_host.ParentGroup.PrimCount + avatarCount;
7691 } 8326 }
7692 8327
@@ -7702,55 +8337,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7702 m_host.AddScriptLPS(1); 8337 m_host.AddScriptLPS(1);
7703 UUID objID = UUID.Zero; 8338 UUID objID = UUID.Zero;
7704 LSL_List result = new LSL_List(); 8339 LSL_List result = new LSL_List();
8340
8341 // If the ID is not valid, return null result
7705 if (!UUID.TryParse(obj, out objID)) 8342 if (!UUID.TryParse(obj, out objID))
7706 { 8343 {
7707 result.Add(new LSL_Vector()); 8344 result.Add(new LSL_Vector());
7708 result.Add(new LSL_Vector()); 8345 result.Add(new LSL_Vector());
7709 return result; 8346 return result;
7710 } 8347 }
8348
8349 // Check if this is an attached prim. If so, replace
8350 // the UUID with the avatar UUID and report it's bounding box
8351 SceneObjectPart part = World.GetSceneObjectPart(objID);
8352 if (part != null && part.ParentGroup.IsAttachment)
8353 objID = part.ParentGroup.AttachedAvatar;
8354
8355 // Find out if this is an avatar ID. If so, return it's box
7711 ScenePresence presence = World.GetScenePresence(objID); 8356 ScenePresence presence = World.GetScenePresence(objID);
7712 if (presence != null) 8357 if (presence != null)
7713 { 8358 {
7714 if (presence.ParentID == 0) // not sat on an object 8359 // As per LSL Wiki, there is no difference between sitting
8360 // and standing avatar since server 1.36
8361 LSL_Vector lower;
8362 LSL_Vector upper;
8363 if (presence.Animator.Animations.DefaultAnimation.AnimID
8364 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7715 { 8365 {
7716 LSL_Vector lower; 8366 // This is for ground sitting avatars
7717 LSL_Vector upper; 8367 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7718 if (presence.Animator.Animations.DefaultAnimation.AnimID 8368 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7719 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8369 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7720 {
7721 // This is for ground sitting avatars
7722 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7723 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7724 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7725 }
7726 else
7727 {
7728 // This is for standing/flying avatars
7729 float height = presence.Appearance.AvatarHeight / 2.0f;
7730 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7731 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7732 }
7733 result.Add(lower);
7734 result.Add(upper);
7735 return result;
7736 } 8370 }
7737 else 8371 else
7738 { 8372 {
7739 // sitting on an object so we need the bounding box of that 8373 // This is for standing/flying avatars
7740 // which should include the avatar so set the UUID to the 8374 float height = presence.Appearance.AvatarHeight / 2.0f;
7741 // UUID of the object the avatar is sat on and allow it to fall through 8375 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7742 // to processing an object 8376 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7743 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7744 objID = p.UUID;
7745 } 8377 }
8378
8379 // Adjust to the documented error offsets (see LSL Wiki)
8380 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8381 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8382
8383 if (lower.x > upper.x)
8384 lower.x = upper.x;
8385 if (lower.y > upper.y)
8386 lower.y = upper.y;
8387 if (lower.z > upper.z)
8388 lower.z = upper.z;
8389
8390 result.Add(lower);
8391 result.Add(upper);
8392 return result;
7746 } 8393 }
7747 SceneObjectPart part = World.GetSceneObjectPart(objID); 8394
8395 part = World.GetSceneObjectPart(objID);
7748 // Currently only works for single prims without a sitting avatar 8396 // Currently only works for single prims without a sitting avatar
7749 if (part != null) 8397 if (part != null)
7750 { 8398 {
7751 Vector3 halfSize = part.Scale / 2.0f; 8399 float minX;
7752 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8400 float maxX;
7753 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8401 float minY;
8402 float maxY;
8403 float minZ;
8404 float maxZ;
8405
8406 // This BBox is in sim coordinates, with the offset being
8407 // a contained point.
8408 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8409 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8410
8411 minX -= offsets[0].X;
8412 maxX -= offsets[0].X;
8413 minY -= offsets[0].Y;
8414 maxY -= offsets[0].Y;
8415 minZ -= offsets[0].Z;
8416 maxZ -= offsets[0].Z;
8417
8418 LSL_Vector lower;
8419 LSL_Vector upper;
8420
8421 // Adjust to the documented error offsets (see LSL Wiki)
8422 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8423 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8424
8425 if (lower.x > upper.x)
8426 lower.x = upper.x;
8427 if (lower.y > upper.y)
8428 lower.y = upper.y;
8429 if (lower.z > upper.z)
8430 lower.z = upper.z;
8431
7754 result.Add(lower); 8432 result.Add(lower);
7755 result.Add(upper); 8433 result.Add(upper);
7756 return result; 8434 return result;
@@ -7764,7 +8442,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7764 8442
7765 public LSL_Vector llGetGeometricCenter() 8443 public LSL_Vector llGetGeometricCenter()
7766 { 8444 {
7767 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8445 Vector3 tmp = m_host.GetGeometricCenter();
8446 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7768 } 8447 }
7769 8448
7770 public LSL_List llGetPrimitiveParams(LSL_List rules) 8449 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7830,13 +8509,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7830 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8509 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7831 part.AbsolutePosition.Y, 8510 part.AbsolutePosition.Y,
7832 part.AbsolutePosition.Z); 8511 part.AbsolutePosition.Z);
7833 // For some reason, the part.AbsolutePosition.* values do not change if the
7834 // linkset is rotated; they always reflect the child prim's world position
7835 // as though the linkset is unrotated. This is incompatible behavior with SL's
7836 // implementation, so will break scripts imported from there (not to mention it
7837 // makes it more difficult to determine a child prim's actual inworld position).
7838 if (part.ParentID != 0)
7839 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7840 res.Add(v); 8512 res.Add(v);
7841 break; 8513 break;
7842 8514
@@ -8007,56 +8679,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8007 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8679 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8008 if (remain < 1) 8680 if (remain < 1)
8009 return res; 8681 return res;
8010 8682 face = (int)rules.GetLSLIntegerItem(idx++);
8011 face=(int)rules.GetLSLIntegerItem(idx++);
8012 8683
8013 tex = part.Shape.Textures; 8684 tex = part.Shape.Textures;
8685 int shiny;
8014 if (face == ScriptBaseClass.ALL_SIDES) 8686 if (face == ScriptBaseClass.ALL_SIDES)
8015 { 8687 {
8016 for (face = 0; face < GetNumberOfSides(part); face++) 8688 for (face = 0; face < GetNumberOfSides(part); face++)
8017 { 8689 {
8018 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8690 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8019 // Convert Shininess to PRIM_SHINY_* 8691 if (shinyness == Shininess.High)
8020 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8692 {
8021 // PRIM_BUMP_* 8693 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8022 res.Add(new LSL_Integer((int)texface.Bump)); 8694 }
8695 else if (shinyness == Shininess.Medium)
8696 {
8697 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8698 }
8699 else if (shinyness == Shininess.Low)
8700 {
8701 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8702 }
8703 else
8704 {
8705 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8706 }
8707 res.Add(new LSL_Integer(shiny));
8708 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8023 } 8709 }
8024 } 8710 }
8025 else 8711 else
8026 { 8712 {
8027 if (face >= 0 && face < GetNumberOfSides(part)) 8713 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8714 if (shinyness == Shininess.High)
8028 { 8715 {
8029 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8716 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8030 // Convert Shininess to PRIM_SHINY_* 8717 }
8031 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8718 else if (shinyness == Shininess.Medium)
8032 // PRIM_BUMP_* 8719 {
8033 res.Add(new LSL_Integer((int)texface.Bump)); 8720 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8721 }
8722 else if (shinyness == Shininess.Low)
8723 {
8724 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8034 } 8725 }
8726 else
8727 {
8728 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8729 }
8730 res.Add(new LSL_Integer(shiny));
8731 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8035 } 8732 }
8036 break; 8733 break;
8037 8734
8038 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8735 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8039 if (remain < 1) 8736 if (remain < 1)
8040 return res; 8737 return res;
8041 8738 face = (int)rules.GetLSLIntegerItem(idx++);
8042 face=(int)rules.GetLSLIntegerItem(idx++);
8043 8739
8044 tex = part.Shape.Textures; 8740 tex = part.Shape.Textures;
8741 int fullbright;
8045 if (face == ScriptBaseClass.ALL_SIDES) 8742 if (face == ScriptBaseClass.ALL_SIDES)
8046 { 8743 {
8047 for (face = 0; face < GetNumberOfSides(part); face++) 8744 for (face = 0; face < GetNumberOfSides(part); face++)
8048 { 8745 {
8049 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8746 if (tex.GetFace((uint)face).Fullbright == true)
8050 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8747 {
8748 fullbright = ScriptBaseClass.TRUE;
8749 }
8750 else
8751 {
8752 fullbright = ScriptBaseClass.FALSE;
8753 }
8754 res.Add(new LSL_Integer(fullbright));
8051 } 8755 }
8052 } 8756 }
8053 else 8757 else
8054 { 8758 {
8055 if (face >= 0 && face < GetNumberOfSides(part)) 8759 if (tex.GetFace((uint)face).Fullbright == true)
8056 { 8760 {
8057 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8761 fullbright = ScriptBaseClass.TRUE;
8058 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8059 } 8762 }
8763 else
8764 {
8765 fullbright = ScriptBaseClass.FALSE;
8766 }
8767 res.Add(new LSL_Integer(fullbright));
8060 } 8768 }
8061 break; 8769 break;
8062 8770
@@ -8078,27 +8786,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8078 break; 8786 break;
8079 8787
8080 case (int)ScriptBaseClass.PRIM_TEXGEN: 8788 case (int)ScriptBaseClass.PRIM_TEXGEN:
8789 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8081 if (remain < 1) 8790 if (remain < 1)
8082 return res; 8791 return res;
8083 8792 face = (int)rules.GetLSLIntegerItem(idx++);
8084 face=(int)rules.GetLSLIntegerItem(idx++);
8085 8793
8086 tex = part.Shape.Textures; 8794 tex = part.Shape.Textures;
8087 if (face == ScriptBaseClass.ALL_SIDES) 8795 if (face == ScriptBaseClass.ALL_SIDES)
8088 { 8796 {
8089 for (face = 0; face < GetNumberOfSides(part); face++) 8797 for (face = 0; face < GetNumberOfSides(part); face++)
8090 { 8798 {
8091 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8799 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8092 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8800 {
8093 res.Add(new LSL_Integer((uint)texgen >> 1)); 8801 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8802 }
8803 else
8804 {
8805 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8806 }
8094 } 8807 }
8095 } 8808 }
8096 else 8809 else
8097 { 8810 {
8098 if (face >= 0 && face < GetNumberOfSides(part)) 8811 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8099 { 8812 {
8100 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8813 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8101 res.Add(new LSL_Integer((uint)texgen >> 1)); 8814 }
8815 else
8816 {
8817 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8102 } 8818 }
8103 } 8819 }
8104 break; 8820 break;
@@ -8121,28 +8837,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8121 case (int)ScriptBaseClass.PRIM_GLOW: 8837 case (int)ScriptBaseClass.PRIM_GLOW:
8122 if (remain < 1) 8838 if (remain < 1)
8123 return res; 8839 return res;
8124 8840 face = (int)rules.GetLSLIntegerItem(idx++);
8125 face=(int)rules.GetLSLIntegerItem(idx++);
8126 8841
8127 tex = part.Shape.Textures; 8842 tex = part.Shape.Textures;
8843 float primglow;
8128 if (face == ScriptBaseClass.ALL_SIDES) 8844 if (face == ScriptBaseClass.ALL_SIDES)
8129 { 8845 {
8130 for (face = 0; face < GetNumberOfSides(part); face++) 8846 for (face = 0; face < GetNumberOfSides(part); face++)
8131 { 8847 {
8132 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8848 primglow = tex.GetFace((uint)face).Glow;
8133 res.Add(new LSL_Float(texface.Glow)); 8849 res.Add(new LSL_Float(primglow));
8134 } 8850 }
8135 } 8851 }
8136 else 8852 else
8137 { 8853 {
8138 if (face >= 0 && face < GetNumberOfSides(part)) 8854 primglow = tex.GetFace((uint)face).Glow;
8139 { 8855 res.Add(new LSL_Float(primglow));
8140 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8141 res.Add(new LSL_Float(texface.Glow));
8142 }
8143 } 8856 }
8144 break; 8857 break;
8145
8146 case (int)ScriptBaseClass.PRIM_TEXT: 8858 case (int)ScriptBaseClass.PRIM_TEXT:
8147 Color4 textColor = part.GetTextColor(); 8859 Color4 textColor = part.GetTextColor();
8148 res.Add(new LSL_String(part.Text)); 8860 res.Add(new LSL_String(part.Text));
@@ -8755,8 +9467,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8755 // The function returns an ordered list 9467 // The function returns an ordered list
8756 // representing the tokens found in the supplied 9468 // representing the tokens found in the supplied
8757 // sources string. If two successive tokenizers 9469 // sources string. If two successive tokenizers
8758 // are encountered, then a NULL entry is added 9470 // are encountered, then a null-string entry is
8759 // to the list. 9471 // added to the list.
8760 // 9472 //
8761 // It is a precondition that the source and 9473 // It is a precondition that the source and
8762 // toekizer lisst are non-null. If they are null, 9474 // toekizer lisst are non-null. If they are null,
@@ -8764,7 +9476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8764 // while their lengths are being determined. 9476 // while their lengths are being determined.
8765 // 9477 //
8766 // A small amount of working memoryis required 9478 // A small amount of working memoryis required
8767 // of approximately 8*#tokenizers. 9479 // of approximately 8*#tokenizers + 8*srcstrlen.
8768 // 9480 //
8769 // There are many ways in which this function 9481 // There are many ways in which this function
8770 // can be implemented, this implementation is 9482 // can be implemented, this implementation is
@@ -8780,155 +9492,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8780 // and eliminates redundant tokenizers as soon 9492 // and eliminates redundant tokenizers as soon
8781 // as is possible. 9493 // as is possible.
8782 // 9494 //
8783 // The implementation tries to avoid any copying 9495 // The implementation tries to minimize temporary
8784 // of arrays or other objects. 9496 // garbage generation.
8785 // </remarks> 9497 // </remarks>
8786 9498
8787 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9499 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8788 { 9500 {
8789 int beginning = 0; 9501 return ParseString2List(src, separators, spacers, true);
8790 int srclen = src.Length; 9502 }
8791 int seplen = separators.Length;
8792 object[] separray = separators.Data;
8793 int spclen = spacers.Length;
8794 object[] spcarray = spacers.Data;
8795 int mlen = seplen+spclen;
8796
8797 int[] offset = new int[mlen+1];
8798 bool[] active = new bool[mlen];
8799
8800 int best;
8801 int j;
8802
8803 // Initial capacity reduces resize cost
8804 9503
8805 LSL_List tokens = new LSL_List(); 9504 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9505 {
9506 int srclen = src.Length;
9507 int seplen = separators.Length;
9508 object[] separray = separators.Data;
9509 int spclen = spacers.Length;
9510 object[] spcarray = spacers.Data;
9511 int dellen = 0;
9512 string[] delarray = new string[seplen+spclen];
8806 9513
8807 // All entries are initially valid 9514 int outlen = 0;
9515 string[] outarray = new string[srclen*2+1];
8808 9516
8809 for (int i = 0; i < mlen; i++) 9517 int i, j;
8810 active[i] = true; 9518 string d;
8811 9519
8812 offset[mlen] = srclen; 9520 m_host.AddScriptLPS(1);
8813 9521
8814 while (beginning < srclen) 9522 /*
9523 * Convert separator and spacer lists to C# strings.
9524 * Also filter out null strings so we don't hang.
9525 */
9526 for (i = 0; i < seplen; i ++)
8815 { 9527 {
9528 d = separray[i].ToString();
9529 if (d.Length > 0)
9530 {
9531 delarray[dellen++] = d;
9532 }
9533 }
9534 seplen = dellen;
8816 9535
8817 best = mlen; // as bad as it gets 9536 for (i = 0; i < spclen; i ++)
9537 {
9538 d = spcarray[i].ToString();
9539 if (d.Length > 0)
9540 {
9541 delarray[dellen++] = d;
9542 }
9543 }
8818 9544
8819 // Scan for separators 9545 /*
9546 * Scan through source string from beginning to end.
9547 */
9548 for (i = 0;;)
9549 {
8820 9550
8821 for (j = 0; j < seplen; j++) 9551 /*
9552 * Find earliest delimeter in src starting at i (if any).
9553 */
9554 int earliestDel = -1;
9555 int earliestSrc = srclen;
9556 string earliestStr = null;
9557 for (j = 0; j < dellen; j ++)
8822 { 9558 {
8823 if (separray[j].ToString() == String.Empty) 9559 d = delarray[j];
8824 active[j] = false; 9560 if (d != null)
8825
8826 if (active[j])
8827 { 9561 {
8828 // scan all of the markers 9562 int index = src.IndexOf(d, i);
8829 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9563 if (index < 0)
8830 { 9564 {
8831 // not present at all 9565 delarray[j] = null; // delim nowhere in src, don't check it anymore
8832 active[j] = false;
8833 } 9566 }
8834 else 9567 else if (index < earliestSrc)
8835 { 9568 {
8836 // present and correct 9569 earliestSrc = index; // where delimeter starts in source string
8837 if (offset[j] < offset[best]) 9570 earliestDel = j; // where delimeter is in delarray[]
8838 { 9571 earliestStr = d; // the delimeter string from delarray[]
8839 // closest so far 9572 if (index == i) break; // can't do any better than found at beg of string
8840 best = j;
8841 if (offset[best] == beginning)
8842 break;
8843 }
8844 } 9573 }
8845 } 9574 }
8846 } 9575 }
8847 9576
8848 // Scan for spacers 9577 /*
8849 9578 * Output source string starting at i through start of earliest delimeter.
8850 if (offset[best] != beginning) 9579 */
9580 if (keepNulls || (earliestSrc > i))
8851 { 9581 {
8852 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9582 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8853 {
8854 if (spcarray[j-seplen].ToString() == String.Empty)
8855 active[j] = false;
8856
8857 if (active[j])
8858 {
8859 // scan all of the markers
8860 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8861 {
8862 // not present at all
8863 active[j] = false;
8864 }
8865 else
8866 {
8867 // present and correct
8868 if (offset[j] < offset[best])
8869 {
8870 // closest so far
8871 best = j;
8872 }
8873 }
8874 }
8875 }
8876 } 9583 }
8877 9584
8878 // This is the normal exit from the scanning loop 9585 /*
9586 * If no delimeter found at or after i, we're done scanning.
9587 */
9588 if (earliestDel < 0) break;
8879 9589
8880 if (best == mlen) 9590 /*
9591 * If delimeter was a spacer, output the spacer.
9592 */
9593 if (earliestDel >= seplen)
8881 { 9594 {
8882 // no markers were found on this pass 9595 outarray[outlen++] = earliestStr;
8883 // so we're pretty much done
8884 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8885 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8886 break;
8887 } 9596 }
8888 9597
8889 // Otherwise we just add the newly delimited token 9598 /*
8890 // and recalculate where the search should continue. 9599 * Look at rest of src string following delimeter.
8891 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9600 */
8892 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9601 i = earliestSrc + earliestStr.Length;
8893
8894 if (best < seplen)
8895 {
8896 beginning = offset[best] + (separray[best].ToString()).Length;
8897 }
8898 else
8899 {
8900 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8901 string str = spcarray[best - seplen].ToString();
8902 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8903 tokens.Add(new LSL_String(str));
8904 }
8905 } 9602 }
8906 9603
8907 // This an awkward an not very intuitive boundary case. If the 9604 /*
8908 // last substring is a tokenizer, then there is an implied trailing 9605 * Make up an exact-sized output array suitable for an LSL_List object.
8909 // null list entry. Hopefully the single comparison will not be too 9606 */
8910 // arduous. Alternatively the 'break' could be replced with a return 9607 object[] outlist = new object[outlen];
8911 // but that's shabby programming. 9608 for (i = 0; i < outlen; i ++)
8912
8913 if ((beginning == srclen) && (keepNulls))
8914 { 9609 {
8915 if (srclen != 0) 9610 outlist[i] = new LSL_String(outarray[i]);
8916 tokens.Add(new LSL_String(""));
8917 } 9611 }
8918 9612 return new LSL_List(outlist);
8919 return tokens;
8920 }
8921
8922 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8923 {
8924 m_host.AddScriptLPS(1);
8925 return this.ParseString(src, separators, spacers, false);
8926 }
8927
8928 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8929 {
8930 m_host.AddScriptLPS(1);
8931 return this.ParseString(src, separators, spacers, true);
8932 } 9613 }
8933 9614
8934 public LSL_Integer llGetObjectPermMask(int mask) 9615 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9005,28 +9686,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9005 { 9686 {
9006 m_host.AddScriptLPS(1); 9687 m_host.AddScriptLPS(1);
9007 9688
9008 lock (m_host.TaskInventory) 9689 m_host.TaskInventory.LockItemsForRead(true);
9690 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9009 { 9691 {
9010 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9692 if (inv.Value.Name == item)
9011 { 9693 {
9012 if (inv.Value.Name == item) 9694 m_host.TaskInventory.LockItemsForRead(false);
9695 switch (mask)
9013 { 9696 {
9014 switch (mask) 9697 case 0:
9015 { 9698 return (int)inv.Value.BasePermissions;
9016 case 0: 9699 case 1:
9017 return (int)inv.Value.BasePermissions; 9700 return (int)inv.Value.CurrentPermissions;
9018 case 1: 9701 case 2:
9019 return (int)inv.Value.CurrentPermissions; 9702 return (int)inv.Value.GroupPermissions;
9020 case 2: 9703 case 3:
9021 return (int)inv.Value.GroupPermissions; 9704 return (int)inv.Value.EveryonePermissions;
9022 case 3: 9705 case 4:
9023 return (int)inv.Value.EveryonePermissions; 9706 return (int)inv.Value.NextPermissions;
9024 case 4:
9025 return (int)inv.Value.NextPermissions;
9026 }
9027 } 9707 }
9028 } 9708 }
9029 } 9709 }
9710 m_host.TaskInventory.LockItemsForRead(false);
9030 9711
9031 return -1; 9712 return -1;
9032 } 9713 }
@@ -9073,16 +9754,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9073 { 9754 {
9074 m_host.AddScriptLPS(1); 9755 m_host.AddScriptLPS(1);
9075 9756
9076 lock (m_host.TaskInventory) 9757 m_host.TaskInventory.LockItemsForRead(true);
9758 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9077 { 9759 {
9078 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9760 if (inv.Value.Name == item)
9079 { 9761 {
9080 if (inv.Value.Name == item) 9762 m_host.TaskInventory.LockItemsForRead(false);
9081 { 9763 return inv.Value.CreatorID.ToString();
9082 return inv.Value.CreatorID.ToString();
9083 }
9084 } 9764 }
9085 } 9765 }
9766 m_host.TaskInventory.LockItemsForRead(false);
9086 9767
9087 llSay(0, "No item name '" + item + "'"); 9768 llSay(0, "No item name '" + item + "'");
9088 9769
@@ -9224,9 +9905,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9224 { 9905 {
9225 try 9906 try
9226 { 9907 {
9908 /*
9227 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9909 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9228 if (obj != null) 9910 if (obj != null)
9229 return (double)obj.GetMass(); 9911 return (double)obj.GetMass();
9912 */
9913 // return total object mass
9914 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9915 if (obj != null)
9916 return obj.GetMass();
9917
9230 // the object is null so the key is for an avatar 9918 // the object is null so the key is for an avatar
9231 ScenePresence avatar = World.GetScenePresence(key); 9919 ScenePresence avatar = World.GetScenePresence(key);
9232 if (avatar != null) 9920 if (avatar != null)
@@ -9246,7 +9934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 } 9934 }
9247 9935
9248 /// <summary> 9936 /// <summary>
9249 /// illListReplaceList removes the sub-list defined by the inclusive indices 9937 /// llListReplaceList removes the sub-list defined by the inclusive indices
9250 /// start and end and inserts the src list in its place. The inclusive 9938 /// start and end and inserts the src list in its place. The inclusive
9251 /// nature of the indices means that at least one element must be deleted 9939 /// nature of the indices means that at least one element must be deleted
9252 /// if the indices are within the bounds of the existing list. I.e. 2,2 9940 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9303,16 +9991,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9303 // based upon end. Note that if end exceeds the upper 9991 // based upon end. Note that if end exceeds the upper
9304 // bound in this case, the entire destination list 9992 // bound in this case, the entire destination list
9305 // is removed. 9993 // is removed.
9306 else 9994 else if (start == 0)
9307 { 9995 {
9308 if (end + 1 < dest.Length) 9996 if (end + 1 < dest.Length)
9309 {
9310 return src + dest.GetSublist(end + 1, -1); 9997 return src + dest.GetSublist(end + 1, -1);
9311 }
9312 else 9998 else
9313 {
9314 return src; 9999 return src;
9315 } 10000 }
10001 else // Start < 0
10002 {
10003 if (end + 1 < dest.Length)
10004 return dest.GetSublist(end + 1, -1);
10005 else
10006 return new LSL_List();
9316 } 10007 }
9317 } 10008 }
9318 // Finally, if start > end, we strip away a prefix and 10009 // Finally, if start > end, we strip away a prefix and
@@ -9363,17 +10054,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9363 int width = 0; 10054 int width = 0;
9364 int height = 0; 10055 int height = 0;
9365 10056
9366 ParcelMediaCommandEnum? commandToSend = null; 10057 uint commandToSend = 0;
9367 float time = 0.0f; // default is from start 10058 float time = 0.0f; // default is from start
9368 10059
9369 ScenePresence presence = null; 10060 ScenePresence presence = null;
9370 10061
9371 for (int i = 0; i < commandList.Data.Length; i++) 10062 for (int i = 0; i < commandList.Data.Length; i++)
9372 { 10063 {
9373 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10064 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9374 switch (command) 10065 switch (command)
9375 { 10066 {
9376 case ParcelMediaCommandEnum.Agent: 10067 case (uint)ParcelMediaCommandEnum.Agent:
9377 // we send only to one agent 10068 // we send only to one agent
9378 if ((i + 1) < commandList.Length) 10069 if ((i + 1) < commandList.Length)
9379 { 10070 {
@@ -9390,25 +10081,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9390 } 10081 }
9391 break; 10082 break;
9392 10083
9393 case ParcelMediaCommandEnum.Loop: 10084 case (uint)ParcelMediaCommandEnum.Loop:
9394 loop = 1; 10085 loop = 1;
9395 commandToSend = command; 10086 commandToSend = command;
9396 update = true; //need to send the media update packet to set looping 10087 update = true; //need to send the media update packet to set looping
9397 break; 10088 break;
9398 10089
9399 case ParcelMediaCommandEnum.Play: 10090 case (uint)ParcelMediaCommandEnum.Play:
9400 loop = 0; 10091 loop = 0;
9401 commandToSend = command; 10092 commandToSend = command;
9402 update = true; //need to send the media update packet to make sure it doesn't loop 10093 update = true; //need to send the media update packet to make sure it doesn't loop
9403 break; 10094 break;
9404 10095
9405 case ParcelMediaCommandEnum.Pause: 10096 case (uint)ParcelMediaCommandEnum.Pause:
9406 case ParcelMediaCommandEnum.Stop: 10097 case (uint)ParcelMediaCommandEnum.Stop:
9407 case ParcelMediaCommandEnum.Unload: 10098 case (uint)ParcelMediaCommandEnum.Unload:
9408 commandToSend = command; 10099 commandToSend = command;
9409 break; 10100 break;
9410 10101
9411 case ParcelMediaCommandEnum.Url: 10102 case (uint)ParcelMediaCommandEnum.Url:
9412 if ((i + 1) < commandList.Length) 10103 if ((i + 1) < commandList.Length)
9413 { 10104 {
9414 if (commandList.Data[i + 1] is LSL_String) 10105 if (commandList.Data[i + 1] is LSL_String)
@@ -9421,7 +10112,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9421 } 10112 }
9422 break; 10113 break;
9423 10114
9424 case ParcelMediaCommandEnum.Texture: 10115 case (uint)ParcelMediaCommandEnum.Texture:
9425 if ((i + 1) < commandList.Length) 10116 if ((i + 1) < commandList.Length)
9426 { 10117 {
9427 if (commandList.Data[i + 1] is LSL_String) 10118 if (commandList.Data[i + 1] is LSL_String)
@@ -9434,7 +10125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9434 } 10125 }
9435 break; 10126 break;
9436 10127
9437 case ParcelMediaCommandEnum.Time: 10128 case (uint)ParcelMediaCommandEnum.Time:
9438 if ((i + 1) < commandList.Length) 10129 if ((i + 1) < commandList.Length)
9439 { 10130 {
9440 if (commandList.Data[i + 1] is LSL_Float) 10131 if (commandList.Data[i + 1] is LSL_Float)
@@ -9446,7 +10137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9446 } 10137 }
9447 break; 10138 break;
9448 10139
9449 case ParcelMediaCommandEnum.AutoAlign: 10140 case (uint)ParcelMediaCommandEnum.AutoAlign:
9450 if ((i + 1) < commandList.Length) 10141 if ((i + 1) < commandList.Length)
9451 { 10142 {
9452 if (commandList.Data[i + 1] is LSL_Integer) 10143 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9460,7 +10151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9460 } 10151 }
9461 break; 10152 break;
9462 10153
9463 case ParcelMediaCommandEnum.Type: 10154 case (uint)ParcelMediaCommandEnum.Type:
9464 if ((i + 1) < commandList.Length) 10155 if ((i + 1) < commandList.Length)
9465 { 10156 {
9466 if (commandList.Data[i + 1] is LSL_String) 10157 if (commandList.Data[i + 1] is LSL_String)
@@ -9473,7 +10164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9473 } 10164 }
9474 break; 10165 break;
9475 10166
9476 case ParcelMediaCommandEnum.Desc: 10167 case (uint)ParcelMediaCommandEnum.Desc:
9477 if ((i + 1) < commandList.Length) 10168 if ((i + 1) < commandList.Length)
9478 { 10169 {
9479 if (commandList.Data[i + 1] is LSL_String) 10170 if (commandList.Data[i + 1] is LSL_String)
@@ -9486,7 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9486 } 10177 }
9487 break; 10178 break;
9488 10179
9489 case ParcelMediaCommandEnum.Size: 10180 case (uint)ParcelMediaCommandEnum.Size:
9490 if ((i + 2) < commandList.Length) 10181 if ((i + 2) < commandList.Length)
9491 { 10182 {
9492 if (commandList.Data[i + 1] is LSL_Integer) 10183 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9556,7 +10247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9556 } 10247 }
9557 } 10248 }
9558 10249
9559 if (commandToSend != null) 10250 if (commandToSend != 0)
9560 { 10251 {
9561 // the commandList contained a start/stop/... command, too 10252 // the commandList contained a start/stop/... command, too
9562 if (presence == null) 10253 if (presence == null)
@@ -9593,7 +10284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9593 10284
9594 if (aList.Data[i] != null) 10285 if (aList.Data[i] != null)
9595 { 10286 {
9596 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10287 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9597 { 10288 {
9598 case ParcelMediaCommandEnum.Url: 10289 case ParcelMediaCommandEnum.Url:
9599 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10290 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9636,16 +10327,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 { 10327 {
9637 m_host.AddScriptLPS(1); 10328 m_host.AddScriptLPS(1);
9638 10329
9639 lock (m_host.TaskInventory) 10330 m_host.TaskInventory.LockItemsForRead(true);
10331 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9640 { 10332 {
9641 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10333 if (inv.Value.Name == name)
9642 { 10334 {
9643 if (inv.Value.Name == name) 10335 m_host.TaskInventory.LockItemsForRead(false);
9644 { 10336 return inv.Value.Type;
9645 return inv.Value.Type;
9646 }
9647 } 10337 }
9648 } 10338 }
10339 m_host.TaskInventory.LockItemsForRead(false);
9649 10340
9650 return -1; 10341 return -1;
9651 } 10342 }
@@ -9656,15 +10347,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 10347
9657 if (quick_pay_buttons.Data.Length < 4) 10348 if (quick_pay_buttons.Data.Length < 4)
9658 { 10349 {
9659 LSLError("List must have at least 4 elements"); 10350 int x;
9660 return; 10351 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10352 {
10353 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10354 }
9661 } 10355 }
9662 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10356 int[] nPrice = new int[5];
9663 10357 nPrice[0] = price;
9664 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10358 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9665 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10359 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9666 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10360 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9667 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10361 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10362 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9668 m_host.ParentGroup.HasGroupChanged = true; 10363 m_host.ParentGroup.HasGroupChanged = true;
9669 } 10364 }
9670 10365
@@ -9680,8 +10375,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 ShoutError("No permissions to track the camera"); 10375 ShoutError("No permissions to track the camera");
9681 return new LSL_Vector(); 10376 return new LSL_Vector();
9682 } 10377 }
10378 m_host.TaskInventory.LockItemsForRead(false);
9683 10379
9684 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10380// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10381 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9685 if (presence != null) 10382 if (presence != null)
9686 { 10383 {
9687 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10384 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9702,8 +10399,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9702 ShoutError("No permissions to track the camera"); 10399 ShoutError("No permissions to track the camera");
9703 return new LSL_Rotation(); 10400 return new LSL_Rotation();
9704 } 10401 }
10402 m_host.TaskInventory.LockItemsForRead(false);
9705 10403
9706 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10404// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10405 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9707 if (presence != null) 10406 if (presence != null)
9708 { 10407 {
9709 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10408 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9763,8 +10462,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9763 { 10462 {
9764 m_host.AddScriptLPS(1); 10463 m_host.AddScriptLPS(1);
9765 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10464 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9766 if (detectedParams == null) return; // only works on the first detected avatar 10465 if (detectedParams == null)
9767 10466 {
10467 if (m_host.ParentGroup.IsAttachment == true)
10468 {
10469 detectedParams = new DetectParams();
10470 detectedParams.Key = m_host.OwnerID;
10471 }
10472 else
10473 {
10474 return;
10475 }
10476 }
10477
9768 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10478 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9769 if (avatar != null) 10479 if (avatar != null)
9770 { 10480 {
@@ -9772,6 +10482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9772 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10482 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9773 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10483 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9774 } 10484 }
10485
9775 ScriptSleep(1000); 10486 ScriptSleep(1000);
9776 } 10487 }
9777 10488
@@ -9895,12 +10606,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9895 10606
9896 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10607 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9897 object[] data = rules.Data; 10608 object[] data = rules.Data;
9898 for (int i = 0; i < data.Length; ++i) { 10609 for (int i = 0; i < data.Length; ++i)
10610 {
9899 int type = Convert.ToInt32(data[i++].ToString()); 10611 int type = Convert.ToInt32(data[i++].ToString());
9900 if (i >= data.Length) break; // odd number of entries => ignore the last 10612 if (i >= data.Length) break; // odd number of entries => ignore the last
9901 10613
9902 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10614 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9903 switch (type) { 10615 switch (type)
10616 {
9904 case ScriptBaseClass.CAMERA_FOCUS: 10617 case ScriptBaseClass.CAMERA_FOCUS:
9905 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10618 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9906 case ScriptBaseClass.CAMERA_POSITION: 10619 case ScriptBaseClass.CAMERA_POSITION:
@@ -10006,19 +10719,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10006 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10719 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10007 { 10720 {
10008 m_host.AddScriptLPS(1); 10721 m_host.AddScriptLPS(1);
10009 string ret = String.Empty; 10722
10010 string src1 = llBase64ToString(str1); 10723 if (str1 == String.Empty)
10011 string src2 = llBase64ToString(str2); 10724 return String.Empty;
10012 int c = 0; 10725 if (str2 == String.Empty)
10013 for (int i = 0; i < src1.Length; i++) 10726 return str1;
10727
10728 int len = str2.Length;
10729 if ((len % 4) != 0) // LL is EVIL!!!!
10014 { 10730 {
10015 ret += (char) (src1[i] ^ src2[c]); 10731 while (str2.EndsWith("="))
10732 str2 = str2.Substring(0, str2.Length - 1);
10016 10733
10017 c++; 10734 len = str2.Length;
10018 if (c >= src2.Length) 10735 int mod = len % 4;
10019 c = 0; 10736
10737 if (mod == 1)
10738 str2 = str2.Substring(0, str2.Length - 1);
10739 else if (mod == 2)
10740 str2 += "==";
10741 else if (mod == 3)
10742 str2 += "=";
10743 }
10744
10745 byte[] data1;
10746 byte[] data2;
10747 try
10748 {
10749 data1 = Convert.FromBase64String(str1);
10750 data2 = Convert.FromBase64String(str2);
10751 }
10752 catch (Exception)
10753 {
10754 return new LSL_String(String.Empty);
10755 }
10756
10757 byte[] d2 = new Byte[data1.Length];
10758 int pos = 0;
10759
10760 if (data1.Length <= data2.Length)
10761 {
10762 Array.Copy(data2, 0, d2, 0, data1.Length);
10020 } 10763 }
10021 return llStringToBase64(ret); 10764 else
10765 {
10766 while (pos < data1.Length)
10767 {
10768 len = data1.Length - pos;
10769 if (len > data2.Length)
10770 len = data2.Length;
10771
10772 Array.Copy(data2, 0, d2, pos, len);
10773 pos += len;
10774 }
10775 }
10776
10777 for (pos = 0 ; pos < data1.Length ; pos++ )
10778 data1[pos] ^= d2[pos];
10779
10780 return Convert.ToBase64String(data1);
10022 } 10781 }
10023 10782
10024 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10783 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10075,12 +10834,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10075 Regex r = new Regex(authregex); 10834 Regex r = new Regex(authregex);
10076 int[] gnums = r.GetGroupNumbers(); 10835 int[] gnums = r.GetGroupNumbers();
10077 Match m = r.Match(url); 10836 Match m = r.Match(url);
10078 if (m.Success) { 10837 if (m.Success)
10079 for (int i = 1; i < gnums.Length; i++) { 10838 {
10839 for (int i = 1; i < gnums.Length; i++)
10840 {
10080 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10841 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10081 //CaptureCollection cc = g.Captures; 10842 //CaptureCollection cc = g.Captures;
10082 } 10843 }
10083 if (m.Groups.Count == 5) { 10844 if (m.Groups.Count == 5)
10845 {
10084 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10846 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10085 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10847 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10086 } 10848 }
@@ -10443,15 +11205,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10443 11205
10444 internal UUID ScriptByName(string name) 11206 internal UUID ScriptByName(string name)
10445 { 11207 {
10446 lock (m_host.TaskInventory) 11208 m_host.TaskInventory.LockItemsForRead(true);
11209
11210 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10447 { 11211 {
10448 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11212 if (item.Type == 10 && item.Name == name)
10449 { 11213 {
10450 if (item.Type == 10 && item.Name == name) 11214 m_host.TaskInventory.LockItemsForRead(false);
10451 return item.ItemID; 11215 return item.ItemID;
10452 } 11216 }
10453 } 11217 }
10454 11218
11219 m_host.TaskInventory.LockItemsForRead(false);
11220
10455 return UUID.Zero; 11221 return UUID.Zero;
10456 } 11222 }
10457 11223
@@ -10492,6 +11258,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10492 { 11258 {
10493 m_host.AddScriptLPS(1); 11259 m_host.AddScriptLPS(1);
10494 11260
11261 //Clone is thread safe
10495 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11262 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10496 11263
10497 UUID assetID = UUID.Zero; 11264 UUID assetID = UUID.Zero;
@@ -10554,6 +11321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10554 { 11321 {
10555 m_host.AddScriptLPS(1); 11322 m_host.AddScriptLPS(1);
10556 11323
11324 //Clone is thread safe
10557 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11325 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10558 11326
10559 UUID assetID = UUID.Zero; 11327 UUID assetID = UUID.Zero;
@@ -10634,15 +11402,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10634 return GetLinkPrimitiveParams(obj, rules); 11402 return GetLinkPrimitiveParams(obj, rules);
10635 } 11403 }
10636 11404
10637 public void print(string str) 11405 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10638 { 11406 {
10639 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11407 List<SceneObjectPart> parts = GetLinkParts(link);
10640 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11408 if (parts.Count < 1)
10641 if (ossl != null) 11409 return 0;
10642 { 11410
10643 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11411 return GetNumberOfSides(parts[0]);
10644 m_log.Info("LSL print():" + str);
10645 }
10646 } 11412 }
10647 11413
10648 private string Name2Username(string name) 11414 private string Name2Username(string name)
@@ -10688,155 +11454,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10688 return rq.ToString(); 11454 return rq.ToString();
10689 } 11455 }
10690 11456
11457 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11458 {
11459 m_SayShoutCount = 0;
11460 }
11461
11462 private struct Tri
11463 {
11464 public Vector3 p1;
11465 public Vector3 p2;
11466 public Vector3 p3;
11467 }
11468
11469 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11470 {
11471 float height = avatar.Appearance.AvatarHeight;
11472 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11473 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11474
11475 if (point.X > b1.X && point.X < b2.X &&
11476 point.Y > b1.Y && point.Y < b2.Y &&
11477 point.Z > b1.Z && point.Z < b2.Z)
11478 return true;
11479 return false;
11480 }
11481
11482 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11483 {
11484 List<ContactResult> contacts = new List<ContactResult>();
11485
11486 Vector3 ab = rayEnd - rayStart;
11487
11488 World.ForEachScenePresence(delegate(ScenePresence sp)
11489 {
11490 Vector3 ac = sp.AbsolutePosition - rayStart;
11491 Vector3 bc = sp.AbsolutePosition - rayEnd;
11492
11493 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11494
11495 if (d > 1.5)
11496 return;
11497
11498 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11499
11500 if (d2 > 0)
11501 return;
11502
11503 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11504 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11505
11506 if (!InBoundingBox(sp, p))
11507 return;
11508
11509 ContactResult result = new ContactResult ();
11510 result.ConsumerID = sp.LocalId;
11511 result.Depth = Vector3.Distance(rayStart, p);
11512 result.Normal = Vector3.Zero;
11513 result.Pos = p;
11514
11515 contacts.Add(result);
11516 });
11517
11518 return contacts.ToArray();
11519 }
11520
11521 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11522 {
11523 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11524 List<ContactResult> contacts = new List<ContactResult>();
11525
11526 Vector3 ab = rayEnd - rayStart;
11527
11528 World.ForEachSOG(delegate(SceneObjectGroup group)
11529 {
11530 if (m_host.ParentGroup == group)
11531 return;
11532
11533 if (group.IsAttachment)
11534 return;
11535
11536 if (group.RootPart.PhysActor == null)
11537 {
11538 if (!includePhantom)
11539 return;
11540 }
11541 else
11542 {
11543 if (group.RootPart.PhysActor.IsPhysical)
11544 {
11545 if (!includePhysical)
11546 return;
11547 }
11548 else
11549 {
11550 if (!includeNonPhysical)
11551 return;
11552 }
11553 }
11554
11555 // Find the radius ouside of which we don't even need to hit test
11556 float minX;
11557 float maxX;
11558 float minY;
11559 float maxY;
11560 float minZ;
11561 float maxZ;
11562
11563 float radius = 0.0f;
11564
11565 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11566
11567 if (Math.Abs(minX) > radius)
11568 radius = Math.Abs(minX);
11569 if (Math.Abs(minY) > radius)
11570 radius = Math.Abs(minY);
11571 if (Math.Abs(minZ) > radius)
11572 radius = Math.Abs(minZ);
11573 if (Math.Abs(maxX) > radius)
11574 radius = Math.Abs(maxX);
11575 if (Math.Abs(maxY) > radius)
11576 radius = Math.Abs(maxY);
11577 if (Math.Abs(maxZ) > radius)
11578 radius = Math.Abs(maxZ);
11579
11580 Vector3 ac = group.AbsolutePosition - rayStart;
11581 Vector3 bc = group.AbsolutePosition - rayEnd;
11582
11583 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11584
11585 // Too far off ray, don't bother
11586 if (d > radius)
11587 return;
11588
11589 // Behind ray, drop
11590 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11591 if (d2 > 0)
11592 return;
11593
11594 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11595 // Miss.
11596 if (!intersection.HitTF)
11597 return;
11598
11599 ContactResult result = new ContactResult ();
11600 result.ConsumerID = group.LocalId;
11601 result.Depth = intersection.distance;
11602 result.Normal = intersection.normal;
11603 result.Pos = intersection.ipoint;
11604
11605 contacts.Add(result);
11606 });
11607
11608 return contacts.ToArray();
11609 }
11610
11611 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11612 {
11613 double[,] heightfield = World.Heightmap.GetDoubles();
11614 List<ContactResult> contacts = new List<ContactResult>();
11615
11616 double min = 2048.0;
11617 double max = 0.0;
11618
11619 // Find the min and max of the heightfield
11620 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11621 {
11622 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11623 {
11624 if (heightfield[x, y] > max)
11625 max = heightfield[x, y];
11626 if (heightfield[x, y] < min)
11627 min = heightfield[x, y];
11628 }
11629 }
11630
11631
11632 // A ray extends past rayEnd, but doesn't go back before
11633 // rayStart. If the start is above the highest point of the ground
11634 // and the ray goes up, we can't hit the ground. Ever.
11635 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11636 return null;
11637
11638 // Same for going down
11639 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11640 return null;
11641
11642 List<Tri> trilist = new List<Tri>();
11643
11644 // Create our triangle list
11645 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11646 {
11647 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11648 {
11649 Tri t1 = new Tri();
11650 Tri t2 = new Tri();
11651
11652 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11653 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11654 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11655 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11656
11657 t1.p1 = p1;
11658 t1.p2 = p2;
11659 t1.p3 = p3;
11660
11661 t2.p1 = p3;
11662 t2.p2 = p4;
11663 t2.p3 = p1;
11664
11665 trilist.Add(t1);
11666 trilist.Add(t2);
11667 }
11668 }
11669
11670 // Ray direction
11671 Vector3 rayDirection = rayEnd - rayStart;
11672
11673 foreach (Tri t in trilist)
11674 {
11675 // Compute triangle plane normal and edges
11676 Vector3 u = t.p2 - t.p1;
11677 Vector3 v = t.p3 - t.p1;
11678 Vector3 n = Vector3.Cross(u, v);
11679
11680 if (n == Vector3.Zero)
11681 continue;
11682
11683 Vector3 w0 = rayStart - t.p1;
11684 double a = -Vector3.Dot(n, w0);
11685 double b = Vector3.Dot(n, rayDirection);
11686
11687 // Not intersecting the plane, or in plane (same thing)
11688 // Ignoring this MAY cause the ground to not be detected
11689 // sometimes
11690 if (Math.Abs(b) < 0.000001)
11691 continue;
11692
11693 double r = a / b;
11694
11695 // ray points away from plane
11696 if (r < 0.0)
11697 continue;
11698
11699 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11700
11701 float uu = Vector3.Dot(u, u);
11702 float uv = Vector3.Dot(u, v);
11703 float vv = Vector3.Dot(v, v);
11704 Vector3 w = ip - t.p1;
11705 float wu = Vector3.Dot(w, u);
11706 float wv = Vector3.Dot(w, v);
11707 float d = uv * uv - uu * vv;
11708
11709 float cs = (uv * wv - vv * wu) / d;
11710 if (cs < 0 || cs > 1.0)
11711 continue;
11712 float ct = (uv * wu - uu * wv) / d;
11713 if (ct < 0 || (cs + ct) > 1.0)
11714 continue;
11715
11716 // Add contact point
11717 ContactResult result = new ContactResult ();
11718 result.ConsumerID = 0;
11719 result.Depth = Vector3.Distance(rayStart, ip);
11720 result.Normal = n;
11721 result.Pos = ip;
11722
11723 contacts.Add(result);
11724 }
11725
11726 if (contacts.Count == 0)
11727 return null;
11728
11729 contacts.Sort(delegate(ContactResult a, ContactResult b)
11730 {
11731 return (int)(a.Depth - b.Depth);
11732 });
11733
11734 return contacts[0];
11735 }
11736/*
11737 // not done:
11738 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11739 {
11740 ContactResult[] contacts = null;
11741 World.ForEachSOG(delegate(SceneObjectGroup group)
11742 {
11743 if (m_host.ParentGroup == group)
11744 return;
11745
11746 if (group.IsAttachment)
11747 return;
11748
11749 if(group.RootPart.PhysActor != null)
11750 return;
11751
11752 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11753 });
11754 return contacts;
11755 }
11756*/
11757
10691 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11758 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10692 { 11759 {
11760 LSL_List list = new LSL_List();
11761
10693 m_host.AddScriptLPS(1); 11762 m_host.AddScriptLPS(1);
10694 11763
10695 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11764 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10696 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11765 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10697 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11766 Vector3 dir = rayEnd - rayStart;
10698 11767
10699 int count = 0; 11768 float dist = Vector3.Mag(dir);
10700// int detectPhantom = 0; 11769
11770 int count = 1;
11771 bool detectPhantom = false;
10701 int dataFlags = 0; 11772 int dataFlags = 0;
10702 int rejectTypes = 0; 11773 int rejectTypes = 0;
10703 11774
10704 for (int i = 0; i < options.Length; i += 2) 11775 for (int i = 0; i < options.Length; i += 2)
10705 { 11776 {
10706 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11777 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10707 {
10708 count = options.GetLSLIntegerItem(i + 1); 11778 count = options.GetLSLIntegerItem(i + 1);
10709 } 11779 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10710// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11780 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10711// {
10712// detectPhantom = options.GetLSLIntegerItem(i + 1);
10713// }
10714 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11781 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10715 {
10716 dataFlags = options.GetLSLIntegerItem(i + 1); 11782 dataFlags = options.GetLSLIntegerItem(i + 1);
10717 }
10718 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11783 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10719 {
10720 rejectTypes = options.GetLSLIntegerItem(i + 1); 11784 rejectTypes = options.GetLSLIntegerItem(i + 1);
10721 }
10722 } 11785 }
10723 11786
10724 LSL_List list = new LSL_List(); 11787 if (count > 16)
10725 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11788 count = 16;
10726
10727 double distance = Util.GetDistanceTo(startvector, endvector);
10728
10729 if (distance == 0)
10730 distance = 0.001;
10731 11789
10732 Vector3 posToCheck = startvector; 11790 List<ContactResult> results = new List<ContactResult>();
10733 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10734 11791
10735 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11792 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10736 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11793 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10737 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11794 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10738 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11795 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10739 11796
10740 for (float i = 0; i <= distance; i += 0.1f) 11797
11798 if (World.SuportsRayCastFiltered())
10741 { 11799 {
10742 posToCheck = startvector + (dir * (i / (float)distance)); 11800 if (dist == 0)
11801 return list;
11802
11803 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11804 if (checkTerrain)
11805 rayfilter |= RayFilterFlags.land;
11806// if (checkAgents)
11807// rayfilter |= RayFilterFlags.agent;
11808 if (checkPhysical)
11809 rayfilter |= RayFilterFlags.physical;
11810 if (checkNonPhysical)
11811 rayfilter |= RayFilterFlags.nonphysical;
11812 if (detectPhantom)
11813 rayfilter |= RayFilterFlags.LSLPhanton;
11814
11815 Vector3 direction = dir * ( 1/dist);
10743 11816
10744 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11817 if(rayfilter == 0)
10745 { 11818 {
10746 ContactResult result = new ContactResult(); 11819 list.Add(new LSL_Integer(0));
10747 result.ConsumerID = 0; 11820 return list;
10748 result.Depth = 0;
10749 result.Normal = Vector3.Zero;
10750 result.Pos = posToCheck;
10751 results.Add(result);
10752 checkTerrain = false;
10753 } 11821 }
10754 11822
10755 if (checkAgents) 11823 // get some more contacts to sort ???
11824 int physcount = 4 * count;
11825 if (physcount > 20)
11826 physcount = 20;
11827
11828 object physresults;
11829 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11830
11831 if (physresults == null)
10756 { 11832 {
10757 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11833 list.Add(new LSL_Integer(-3)); // timeout error
10758 { 11834 return list;
10759 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
10760 {
10761 ContactResult result = new ContactResult ();
10762 result.ConsumerID = sp.LocalId;
10763 result.Depth = 0;
10764 result.Normal = Vector3.Zero;
10765 result.Pos = posToCheck;
10766 results.Add(result);
10767 }
10768 });
10769 } 11835 }
10770 }
10771 11836
10772 int refcount = 0; 11837 results = (List<ContactResult>)physresults;
10773 foreach (ContactResult result in results) 11838
10774 { 11839 // for now physics doesn't detect sitted avatars so do it outside physics
10775 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11840 if (checkAgents)
10776 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11841 {
10777 continue; 11842 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11843 foreach (ContactResult r in agentHits)
11844 results.Add(r);
11845 }
10778 11846
10779 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11847 // bug: will not detect phantom unless they are physical
11848 // don't use ObjectIntersection because its also bad
10780 11849
10781 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11850 }
10782 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11851 else
11852 {
11853 if (checkTerrain)
11854 {
11855 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11856 if (groundContact != null)
11857 results.Add((ContactResult)groundContact);
11858 }
10783 11859
10784 if (entity == null) 11860 if (checkAgents)
10785 { 11861 {
10786 list.Add(UUID.Zero); 11862 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11863 foreach (ContactResult r in agentHits)
11864 results.Add(r);
11865 }
10787 11866
10788 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11867 if (checkPhysical || checkNonPhysical || detectPhantom)
10789 list.Add(0); 11868 {
11869 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11870 foreach (ContactResult r in objectHits)
11871 results.Add(r);
11872 }
11873 }
10790 11874
10791 list.Add(result.Pos); 11875 results.Sort(delegate(ContactResult a, ContactResult b)
11876 {
11877 return a.Depth.CompareTo(b.Depth);
11878 });
11879
11880 int values = 0;
11881 SceneObjectGroup thisgrp = m_host.ParentGroup;
10792 11882
10793 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11883 foreach (ContactResult result in results)
10794 list.Add(result.Normal); 11884 {
11885 if (result.Depth > dist)
11886 continue;
10795 11887
10796 continue; //Can't find it, so add UUID.Zero 11888 // physics ray can return colisions with host prim
10797 } 11889 if (m_host.LocalId == result.ConsumerID)
11890 continue;
10798 11891
10799 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11892 UUID itemID = UUID.Zero;
10800 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11893 int linkNum = 0;
10801 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10802 11894
10803 if (entity is SceneObjectPart) 11895 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11896 // It's a prim!
11897 if (part != null)
10804 { 11898 {
10805 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11899 // dont detect members of same object ???
11900 if (part.ParentGroup == thisgrp)
11901 continue;
10806 11902
10807 if (pa != null && pa.IsPhysical) 11903 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10808 { 11904 itemID = part.ParentGroup.UUID;
10809 if (!checkPhysical)
10810 continue;
10811 }
10812 else 11905 else
10813 { 11906 itemID = part.UUID;
10814 if (!checkNonPhysical)
10815 continue;
10816 }
10817 }
10818 11907
10819 refcount++; 11908 linkNum = part.LinkNum;
10820 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11909 }
10821 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10822 else 11910 else
10823 list.Add(entity.UUID);
10824
10825 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10826 { 11911 {
10827 if (entity is SceneObjectPart) 11912 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10828 list.Add(((SceneObjectPart)entity).LinkNum); 11913 /// It it a boy? a girl?
10829 else 11914 if (sp != null)
10830 list.Add(0); 11915 itemID = sp.UUID;
10831 } 11916 }
10832 11917
10833 list.Add(result.Pos); 11918 list.Add(new LSL_String(itemID.ToString()));
11919 list.Add(new LSL_String(result.Pos.ToString()));
11920
11921 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11922 list.Add(new LSL_Integer(linkNum));
10834 11923
10835 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11924 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10836 list.Add(result.Normal); 11925 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11926
11927 values++;
11928 if (values >= count)
11929 break;
10837 } 11930 }
10838 11931
10839 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11932 list.Add(new LSL_Integer(values));
10840 11933
10841 return list; 11934 return list;
10842 } 11935 }
@@ -10876,7 +11969,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10876 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11969 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10877 if (!isAccount) return 0; 11970 if (!isAccount) return 0;
10878 if (estate.HasAccess(id)) return 1; 11971 if (estate.HasAccess(id)) return 1;
10879 if (estate.IsBanned(id)) 11972 if (estate.IsBanned(id, World.GetUserFlags(id)))
10880 estate.RemoveBan(id); 11973 estate.RemoveBan(id);
10881 estate.AddEstateUser(id); 11974 estate.AddEstateUser(id);
10882 break; 11975 break;
@@ -10895,14 +11988,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10895 break; 11988 break;
10896 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11989 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10897 if (!isAccount) return 0; 11990 if (!isAccount) return 0;
10898 if (estate.IsBanned(id)) return 1; 11991 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10899 EstateBan ban = new EstateBan(); 11992 EstateBan ban = new EstateBan();
10900 ban.EstateID = estate.EstateID; 11993 ban.EstateID = estate.EstateID;
10901 ban.BannedUserID = id; 11994 ban.BannedUserID = id;
10902 estate.AddBan(ban); 11995 estate.AddBan(ban);
10903 break; 11996 break;
10904 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11997 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10905 if (!isAccount || !estate.IsBanned(id)) return 0; 11998 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10906 estate.RemoveBan(id); 11999 estate.RemoveBan(id);
10907 break; 12000 break;
10908 default: return 0; 12001 default: return 0;
@@ -10931,7 +12024,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10931 return 16384; 12024 return 16384;
10932 } 12025 }
10933 12026
10934 public LSL_Integer llGetUsedMemory() 12027 public virtual LSL_Integer llGetUsedMemory()
10935 { 12028 {
10936 m_host.AddScriptLPS(1); 12029 m_host.AddScriptLPS(1);
10937 // The value returned for LSO scripts in SL 12030 // The value returned for LSO scripts in SL
@@ -10959,7 +12052,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10959 public void llSetSoundQueueing(int queue) 12052 public void llSetSoundQueueing(int queue)
10960 { 12053 {
10961 m_host.AddScriptLPS(1); 12054 m_host.AddScriptLPS(1);
10962 NotImplemented("llSetSoundQueueing");
10963 } 12055 }
10964 12056
10965 public void llCollisionSprite(string impact_sprite) 12057 public void llCollisionSprite(string impact_sprite)
@@ -10971,10 +12063,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10971 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12063 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10972 { 12064 {
10973 m_host.AddScriptLPS(1); 12065 m_host.AddScriptLPS(1);
10974 NotImplemented("llGodLikeRezObject"); 12066
12067 if (!World.Permissions.IsGod(m_host.OwnerID))
12068 NotImplemented("llGodLikeRezObject");
12069
12070 AssetBase rezAsset = World.AssetService.Get(inventory);
12071 if (rezAsset == null)
12072 {
12073 llSay(0, "Asset not found");
12074 return;
12075 }
12076
12077 SceneObjectGroup group = null;
12078
12079 try
12080 {
12081 string xmlData = Utils.BytesToString(rezAsset.Data);
12082 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12083 }
12084 catch
12085 {
12086 llSay(0, "Asset not found");
12087 return;
12088 }
12089
12090 if (group == null)
12091 {
12092 llSay(0, "Asset not found");
12093 return;
12094 }
12095
12096 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12097 group.RootPart.AttachOffset = group.AbsolutePosition;
12098
12099 group.ResetIDs();
12100
12101 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12102 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12103 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12104 group.ScheduleGroupForFullUpdate();
12105
12106 // objects rezzed with this method are die_at_edge by default.
12107 group.RootPart.SetDieAtEdge(true);
12108
12109 group.ResumeScripts();
12110
12111 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12112 "object_rez", new Object[] {
12113 new LSL_String(
12114 group.RootPart.UUID.ToString()) },
12115 new DetectParams[0]));
12116 }
12117
12118 public LSL_String llTransferLindenDollars(string destination, int amount)
12119 {
12120 UUID txn = UUID.Random();
12121
12122 Util.FireAndForget(delegate(object x)
12123 {
12124 int replycode = 0;
12125 string replydata = destination + "," + amount.ToString();
12126
12127 try
12128 {
12129 TaskInventoryItem item = m_item;
12130 if (item == null)
12131 {
12132 replydata = "SERVICE_ERROR";
12133 return;
12134 }
12135
12136 m_host.AddScriptLPS(1);
12137
12138 if (item.PermsGranter == UUID.Zero)
12139 {
12140 replydata = "MISSING_PERMISSION_DEBIT";
12141 return;
12142 }
12143
12144 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12145 {
12146 replydata = "MISSING_PERMISSION_DEBIT";
12147 return;
12148 }
12149
12150 UUID toID = new UUID();
12151
12152 if (!UUID.TryParse(destination, out toID))
12153 {
12154 replydata = "INVALID_AGENT";
12155 return;
12156 }
12157
12158 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12159
12160 if (money == null)
12161 {
12162 replydata = "TRANSFERS_DISABLED";
12163 return;
12164 }
12165
12166 bool result = money.ObjectGiveMoney(
12167 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12168
12169 if (result)
12170 {
12171 replycode = 1;
12172 return;
12173 }
12174
12175 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12176 }
12177 finally
12178 {
12179 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12180 "transaction_result", new Object[] {
12181 new LSL_String(txn.ToString()),
12182 new LSL_Integer(replycode),
12183 new LSL_String(replydata) },
12184 new DetectParams[0]));
12185 }
12186 });
12187
12188 return txn.ToString();
10975 } 12189 }
10976 12190
10977 #endregion 12191 #endregion
12192
12193 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12194 {
12195 SceneObjectGroup group = m_host.ParentGroup;
12196
12197 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12198 return;
12199 if (group.IsAttachment)
12200 return;
12201
12202 if (frames.Data.Length > 0) // We are getting a new motion
12203 {
12204 if (group.RootPart.KeyframeMotion != null)
12205 group.RootPart.KeyframeMotion.Stop();
12206 group.RootPart.KeyframeMotion = null;
12207
12208 int idx = 0;
12209
12210 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12211 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12212
12213 while (idx < options.Data.Length)
12214 {
12215 int option = (int)options.GetLSLIntegerItem(idx++);
12216 int remain = options.Data.Length - idx;
12217
12218 switch (option)
12219 {
12220 case ScriptBaseClass.KFM_MODE:
12221 if (remain < 1)
12222 break;
12223 int modeval = (int)options.GetLSLIntegerItem(idx++);
12224 switch(modeval)
12225 {
12226 case ScriptBaseClass.KFM_FORWARD:
12227 mode = KeyframeMotion.PlayMode.Forward;
12228 break;
12229 case ScriptBaseClass.KFM_REVERSE:
12230 mode = KeyframeMotion.PlayMode.Reverse;
12231 break;
12232 case ScriptBaseClass.KFM_LOOP:
12233 mode = KeyframeMotion.PlayMode.Loop;
12234 break;
12235 case ScriptBaseClass.KFM_PING_PONG:
12236 mode = KeyframeMotion.PlayMode.PingPong;
12237 break;
12238 }
12239 break;
12240 case ScriptBaseClass.KFM_DATA:
12241 if (remain < 1)
12242 break;
12243 int dataval = (int)options.GetLSLIntegerItem(idx++);
12244 data = (KeyframeMotion.DataFormat)dataval;
12245 break;
12246 }
12247 }
12248
12249 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12250
12251 idx = 0;
12252
12253 int elemLength = 2;
12254 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12255 elemLength = 3;
12256
12257 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12258 while (idx < frames.Data.Length)
12259 {
12260 int remain = frames.Data.Length - idx;
12261
12262 if (remain < elemLength)
12263 break;
12264
12265 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12266 frame.Position = null;
12267 frame.Rotation = null;
12268
12269 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12270 {
12271 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12272 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12273 }
12274 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12275 {
12276 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12277 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12278 }
12279
12280 float tempf = (float)frames.GetLSLFloatItem(idx++);
12281 frame.TimeMS = (int)(tempf * 1000.0f);
12282
12283 keyframes.Add(frame);
12284 }
12285
12286 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12287 group.RootPart.KeyframeMotion.Start();
12288 }
12289 else
12290 {
12291 if (group.RootPart.KeyframeMotion == null)
12292 return;
12293
12294 if (options.Data.Length == 0)
12295 {
12296 group.RootPart.KeyframeMotion.Stop();
12297 return;
12298 }
12299
12300 int code = (int)options.GetLSLIntegerItem(0);
12301
12302 int idx = 0;
12303
12304 while (idx < options.Data.Length)
12305 {
12306 int option = (int)options.GetLSLIntegerItem(idx++);
12307 int remain = options.Data.Length - idx;
12308
12309 switch (option)
12310 {
12311 case ScriptBaseClass.KFM_COMMAND:
12312 int cmd = (int)options.GetLSLIntegerItem(idx++);
12313 switch (cmd)
12314 {
12315 case ScriptBaseClass.KFM_CMD_PLAY:
12316 group.RootPart.KeyframeMotion.Start();
12317 break;
12318 case ScriptBaseClass.KFM_CMD_STOP:
12319 group.RootPart.KeyframeMotion.Stop();
12320 break;
12321 case ScriptBaseClass.KFM_CMD_PAUSE:
12322 group.RootPart.KeyframeMotion.Pause();
12323 break;
12324 }
12325 break;
12326 }
12327 }
12328 }
12329 }
10978 } 12330 }
10979 12331
10980 public class NotecardCache 12332 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7ea8b7a..8237b60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -920,18 +929,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
920 if (target != null) 929 if (target != null)
921 { 930 {
922 UUID animID=UUID.Zero; 931 UUID animID=UUID.Zero;
923 lock (m_host.TaskInventory) 932 m_host.TaskInventory.LockItemsForRead(true);
933 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
924 { 934 {
925 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 935 if (inv.Value.Name == animation)
926 { 936 {
927 if (inv.Value.Name == animation) 937 if (inv.Value.Type == (int)AssetType.Animation)
928 { 938 animID = inv.Value.AssetID;
929 if (inv.Value.Type == (int)AssetType.Animation) 939 continue;
930 animID = inv.Value.AssetID;
931 continue;
932 }
933 } 940 }
934 } 941 }
942 m_host.TaskInventory.LockItemsForRead(false);
935 if (animID == UUID.Zero) 943 if (animID == UUID.Zero)
936 target.Animator.AddAnimation(animation, m_host.UUID); 944 target.Animator.AddAnimation(animation, m_host.UUID);
937 else 945 else
@@ -972,6 +980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
972 else 980 else
973 animID = UUID.Zero; 981 animID = UUID.Zero;
974 } 982 }
983 m_host.TaskInventory.LockItemsForRead(false);
975 984
976 if (animID == UUID.Zero) 985 if (animID == UUID.Zero)
977 target.Animator.RemoveAnimation(animation); 986 target.Animator.RemoveAnimation(animation);
@@ -1792,6 +1801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1801
1793 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1794 { 1803 {
1804 m_host.TaskInventory.LockItemsForRead(true);
1795 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1805 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1796 { 1806 {
1797 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1807 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1799,6 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 assetID = item.AssetID; 1809 assetID = item.AssetID;
1800 } 1810 }
1801 } 1811 }
1812 m_host.TaskInventory.LockItemsForRead(false);
1802 } 1813 }
1803 1814
1804 if (assetID == UUID.Zero) 1815 if (assetID == UUID.Zero)
@@ -2266,7 +2277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2266 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2277 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2267 m_host.AddScriptLPS(1); 2278 m_host.AddScriptLPS(1);
2268 2279
2269 return NpcCreate(firstname, lastname, position, notecard, false, false); 2280 return NpcCreate(firstname, lastname, position, notecard, true, false);
2270 } 2281 }
2271 2282
2272 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2283 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2277,24 +2288,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2277 return NpcCreate( 2288 return NpcCreate(
2278 firstname, lastname, position, notecard, 2289 firstname, lastname, position, notecard,
2279 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2290 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2280 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2291 false);
2292// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2281 } 2293 }
2282 2294
2283 private LSL_Key NpcCreate( 2295 private LSL_Key NpcCreate(
2284 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2296 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2285 { 2297 {
2298 if (!owned)
2299 OSSLError("Unowned NPCs are unsupported");
2300
2301 string groupTitle = String.Empty;
2302
2303 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2304 return new LSL_Key(UUID.Zero.ToString());
2305
2306 if (firstname != String.Empty || lastname != String.Empty)
2307 {
2308 if (firstname != "Shown outfit:")
2309 groupTitle = "- NPC -";
2310 }
2311
2286 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2312 INPCModule module = World.RequestModuleInterface<INPCModule>();
2287 if (module != null) 2313 if (module != null)
2288 { 2314 {
2289 AvatarAppearance appearance = null; 2315 AvatarAppearance appearance = null;
2290 2316
2291 UUID id; 2317// UUID id;
2292 if (UUID.TryParse(notecard, out id)) 2318// if (UUID.TryParse(notecard, out id))
2293 { 2319// {
2294 ScenePresence clonePresence = World.GetScenePresence(id); 2320// ScenePresence clonePresence = World.GetScenePresence(id);
2295 if (clonePresence != null) 2321// if (clonePresence != null)
2296 appearance = clonePresence.Appearance; 2322// appearance = clonePresence.Appearance;
2297 } 2323// }
2298 2324
2299 if (appearance == null) 2325 if (appearance == null)
2300 { 2326 {
@@ -2322,6 +2348,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 World, 2348 World,
2323 appearance); 2349 appearance);
2324 2350
2351 ScenePresence sp;
2352 if (World.TryGetScenePresence(x, out sp))
2353 {
2354 sp.Grouptitle = groupTitle;
2355 sp.SendAvatarDataToAllAgents();
2356 }
2325 return new LSL_Key(x.ToString()); 2357 return new LSL_Key(x.ToString());
2326 } 2358 }
2327 2359
@@ -2613,16 +2645,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2613 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2645 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2614 m_host.AddScriptLPS(1); 2646 m_host.AddScriptLPS(1);
2615 2647
2616 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2648 ManualResetEvent ev = new ManualResetEvent(false);
2617 if (module != null)
2618 {
2619 UUID npcId = new UUID(npc.m_string);
2620 2649
2621 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2650 Util.FireAndForget(delegate(object x) {
2622 return; 2651 try
2652 {
2653 INPCModule module = World.RequestModuleInterface<INPCModule>();
2654 if (module != null)
2655 {
2656 UUID npcId = new UUID(npc.m_string);
2623 2657
2624 module.DeleteNPC(npcId, World); 2658 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2625 } 2659 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2660 {
2661 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2662 return;
2663 }
2664
2665 module.DeleteNPC(npcId, World);
2666 }
2667 }
2668 finally
2669 {
2670 ev.Set();
2671 }
2672 });
2673 ev.WaitOne();
2626 } 2674 }
2627 2675
2628 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2676 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3156,4 +3204,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3204 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3157 } 3205 }
3158 } 3206 }
3159} \ No newline at end of file 3207}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.GetWorldRotation(); 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 7f5d1fe..048124d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -355,6 +357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 357 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 358 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 359 void llSetPos(LSL_Vector pos);
360 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 361 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 362 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 363 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -403,6 +406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
403 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 406 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
404 void llTargetRemove(int number); 407 void llTargetRemove(int number);
405 void llTeleportAgentHome(string agent); 408 void llTeleportAgentHome(string agent);
409 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
406 void llTextBox(string avatar, string message, int chat_channel); 410 void llTextBox(string avatar, string message, int chat_channel);
407 LSL_String llToLower(string source); 411 LSL_String llToLower(string source);
408 LSL_String llToUpper(string source); 412 LSL_String llToUpper(string source);
@@ -419,9 +423,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
419 LSL_Vector llWind(LSL_Vector offset); 423 LSL_Vector llWind(LSL_Vector offset);
420 LSL_String llXorBase64Strings(string str1, string str2); 424 LSL_String llXorBase64Strings(string str1, string str2);
421 LSL_String llXorBase64StringsCorrect(string str1, string str2); 425 LSL_String llXorBase64StringsCorrect(string str1, string str2);
422 void print(string str); 426 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
427 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
423 428
424 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
425 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 430 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
426 } 432 }
427} 433}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index e92518d..7382495 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b6c21e6..5c6ad8a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -586,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
586 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
587 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
588 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
589 602
590 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
591 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -659,5 +672,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
659 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
660 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
661 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
662 } 688 }
663} 689}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c0bf29c..2d23d30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -474,6 +481,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 481 return m_LSL_Functions.llGetFreeMemory();
475 } 482 }
476 483
484 public LSL_Integer llGetUsedMemory()
485 {
486 return m_LSL_Functions.llGetUsedMemory();
487 }
488
477 public LSL_Integer llGetFreeURLs() 489 public LSL_Integer llGetFreeURLs()
478 { 490 {
479 return m_LSL_Functions.llGetFreeURLs(); 491 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 591 return m_LSL_Functions.llGetMass();
580 } 592 }
581 593
594 public LSL_Float llGetMassMKS()
595 {
596 return m_LSL_Functions.llGetMassMKS();
597 }
598
582 public LSL_Integer llGetMemoryLimit() 599 public LSL_Integer llGetMemoryLimit()
583 { 600 {
584 return m_LSL_Functions.llGetMemoryLimit(); 601 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +861,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 861 return m_LSL_Functions.llGetUnixTime();
845 } 862 }
846 863
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 864 public LSL_Vector llGetVel()
853 { 865 {
854 return m_LSL_Functions.llGetVel(); 866 return m_LSL_Functions.llGetVel();
@@ -874,6 +886,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 886 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 887 }
876 888
889 public LSL_String llTransferLindenDollars(string destination, int amount)
890 {
891 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
892 }
893
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 894 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 895 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 896 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1598,6 +1615,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1598 m_LSL_Functions.llSetPos(pos); 1615 m_LSL_Functions.llSetPos(pos);
1599 } 1616 }
1600 1617
1618 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1619 {
1620 return m_LSL_Functions.llSetRegionPos(pos);
1621 }
1622
1601 public void llSetPrimitiveParams(LSL_List rules) 1623 public void llSetPrimitiveParams(LSL_List rules)
1602 { 1624 {
1603 m_LSL_Functions.llSetPrimitiveParams(rules); 1625 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1833,6 +1855,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1833 m_LSL_Functions.llTargetRemove(number); 1855 m_LSL_Functions.llTargetRemove(number);
1834 } 1856 }
1835 1857
1858 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1859 {
1860 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1861 }
1862
1836 public void llTeleportAgentHome(string agent) 1863 public void llTeleportAgentHome(string agent)
1837 { 1864 {
1838 m_LSL_Functions.llTeleportAgentHome(agent); 1865 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1948,9 +1975,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1948 return m_LSL_Functions.llClearLinkMedia(link, face); 1975 return m_LSL_Functions.llClearLinkMedia(link, face);
1949 } 1976 }
1950 1977
1951 public void print(string str) 1978 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1979 {
1980 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1981 }
1982
1983 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1984 {
1985 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1986 }
1987
1988 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1952 { 1989 {
1953 m_LSL_Functions.print(str); 1990 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1954 } 1991 }
1955 } 1992 }
1956} 1993}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);