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.cs3022
-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, 2657 insertions, 877 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..3b8efd5 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,48 @@ 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;
118
119 private Dictionary<string, string> MovementAnimationsForLSL =
120 new Dictionary<string, string> {
121 {"FLY", "Flying"},
122 {"FLYSLOW", "FlyingSlow"},
123 {"HOVER_UP", "Hovering Up"},
124 {"HOVER_DOWN", "Hovering Down"},
125 {"HOVER", "Hovering"},
126 {"LAND", "Landing"},
127 {"FALLDOWN", "Falling Down"},
128 {"PREJUMP", "PreJumping"},
129 {"JUMP", "Jumping"},
130 {"STANDUP", "Standing Up"},
131 {"SOFT_LAND", "Soft Landing"},
132 {"STAND", "Standing"},
133 {"CROUCHWALK", "CrouchWalking"},
134 {"RUN", "Running"},
135 {"WALK", "Walking"},
136 {"CROUCH", "Crouching"},
137 {"TURNLEFT", "Turning Left"},
138 {"TURNRIGHT", "Turning Right"}
139 };
109 140
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 142 {
143 m_ShoutSayTimer = new Timer(1000);
144 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
145 m_ShoutSayTimer.AutoReset = true;
146 m_ShoutSayTimer.Start();
147
112 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
113 m_host = host; 149 m_host = host;
114 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 152
116 LoadLimits(); // read script limits from config. 153 LoadLimits(); // read script limits from config.
117 154
@@ -171,6 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 208 get { return m_ScriptEngine.World; }
172 } 209 }
173 210
211 [DebuggerNonUserCode]
174 public void state(string newState) 212 public void state(string newState)
175 { 213 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 214 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 218 /// Reset the named script. The script must be present
181 /// in the same prim. 219 /// in the same prim.
182 /// </summary> 220 /// </summary>
221 [DebuggerNonUserCode]
183 public void llResetScript() 222 public void llResetScript()
184 { 223 {
185 m_host.AddScriptLPS(1); 224 m_host.AddScriptLPS(1);
@@ -236,9 +275,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 275 }
237 } 276 }
238 277
278 public List<ScenePresence> GetLinkAvatars(int linkType)
279 {
280 List<ScenePresence> ret = new List<ScenePresence>();
281 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
282 return ret;
283
284 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
285
286 switch (linkType)
287 {
288 case ScriptBaseClass.LINK_SET:
289 return avs;
290
291 case ScriptBaseClass.LINK_ROOT:
292 return ret;
293
294 case ScriptBaseClass.LINK_ALL_OTHERS:
295 return avs;
296
297 case ScriptBaseClass.LINK_ALL_CHILDREN:
298 return avs;
299
300 case ScriptBaseClass.LINK_THIS:
301 return ret;
302
303 default:
304 if (linkType < 0)
305 return ret;
306
307 int partCount = m_host.ParentGroup.GetPartCount();
308
309 if (linkType <= partCount)
310 {
311 return ret;
312 }
313 else
314 {
315 linkType = linkType - partCount;
316 if (linkType > avs.Count)
317 {
318 return ret;
319 }
320 else
321 {
322 ret.Add(avs[linkType-1]);
323 return ret;
324 }
325 }
326 }
327 }
328
239 public List<SceneObjectPart> GetLinkParts(int linkType) 329 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 330 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 331 List<SceneObjectPart> ret = new List<SceneObjectPart>();
332 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
333 return ret;
242 ret.Add(m_host); 334 ret.Add(m_host);
243 335
244 switch (linkType) 336 switch (linkType)
@@ -432,31 +524,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
432 524
433 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 525 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
434 526
435 /// <summary> 527 // Utility function for llRot2Euler
436 /// Convert an LSL rotation to a Euler vector. 528
437 /// </summary> 529 // normalize an angle between -PI and PI (-180 to +180 degrees)
438 /// <remarks> 530 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 { 531 {
446 m_host.AddScriptLPS(1); 532 if (angle > -Math.PI && angle < Math.PI)
533 return angle;
534
535 int numPis = (int)(Math.PI / angle);
536 double remainder = angle - Math.PI * numPis;
537 if (numPis % 2 == 1)
538 return Math.PI - angle;
539 return remainder;
540 }
447 541
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. 542 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. 543 {
450 if (m == 0.0) return new LSL_Vector(); 544 m_host.AddScriptLPS(1);
451 double x = Math.Atan2(-v.y, v.z); 545 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 546
459 return new LSL_Vector(x, y, z); 547 double sqw = q1.s*q1.s;
548 double sqx = q1.x*q1.x;
549 double sqy = q1.z*q1.z;
550 double sqz = q1.y*q1.y;
551 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
552 double test = q1.x*q1.z + q1.y*q1.s;
553 if (test > 0.4999*unit) { // singularity at north pole
554 eul.z = 2 * Math.Atan2(q1.x,q1.s);
555 eul.y = Math.PI/2;
556 eul.x = 0;
557 return eul;
558 }
559 if (test < -0.4999*unit) { // singularity at south pole
560 eul.z = -2 * Math.Atan2(q1.x,q1.s);
561 eul.y = -Math.PI/2;
562 eul.x = 0;
563 return eul;
564 }
565 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
566 eul.y = Math.Asin(2*test/unit);
567 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
568 return eul;
460 } 569 }
461 570
462 /* From wiki: 571 /* From wiki:
@@ -658,77 +767,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
658 { 767 {
659 //A and B should both be normalized 768 //A and B should both be normalized
660 m_host.AddScriptLPS(1); 769 m_host.AddScriptLPS(1);
661 LSL_Rotation rotBetween; 770 /* 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, 771 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
663 // continue calculation. 772
664 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 773 double dotProduct = LSL_Vector.Dot(a, b);
774 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
775 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
776 double angle = Math.Acos(dotProduct / magProduct);
777 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
778 double s = Math.Sin(angle / 2);
779
780 double x = axis.x * s;
781 double y = axis.y * s;
782 double z = axis.z * s;
783 double w = Math.Cos(angle / 2);
784
785 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
786 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
787
788 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
789 */
790
791 // This method mimics the 180 errors found in SL
792 // See www.euclideanspace.com... angleBetween
793 LSL_Vector vec_a = a;
794 LSL_Vector vec_b = b;
795
796 // Eliminate zero length
797 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
798 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
799 if (vec_a_mag < 0.00001 ||
800 vec_b_mag < 0.00001)
665 { 801 {
666 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 802 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
667 } 803 }
668 else 804
805 // Normalize
806 vec_a = llVecNorm(vec_a);
807 vec_b = llVecNorm(vec_b);
808
809 // Calculate axis and rotation angle
810 LSL_Vector axis = vec_a % vec_b;
811 LSL_Float cos_theta = vec_a * vec_b;
812
813 // Check if parallel
814 if (cos_theta > 0.99999)
669 { 815 {
670 a = LSL_Vector.Norm(a); 816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
671 b = LSL_Vector.Norm(b); 817 }
672 double dotProduct = LSL_Vector.Dot(a, b); 818
673 // There are two degenerate cases possible. These are for vectors 180 or 819 // Check if anti-parallel
674 // 0 degrees apart. These have to be detected and handled individually. 820 else if (cos_theta < -0.99999)
675 // 821 {
676 // Check for vectors 180 degrees apart. 822 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. 823 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
678 if (dotProduct < -0.9999999f) 824 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
679 { 825 }
680 // First assume X axis is orthogonal to the vectors. 826 else // other rotation
681 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 827 {
682 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 828 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 829 axis = llVecNorm(axis);
684 // a rotation in an undesired direction. 830 double x, y, z, s, t;
685 if (LSL_Vector.Mag(orthoVector) > 0.0001) 831 s = Math.Cos(theta);
686 { 832 t = Math.Sin(theta);
687 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 833 x = axis.x * t;
688 } 834 y = axis.y * t;
689 // If the magnitude of the vector was near zero, then assume the X axis is not 835 z = axis.z * t;
690 // orthogonal and use the Z axis instead. 836 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 } 837 }
729 return rotBetween;
730 } 838 }
731 839
732 public void llWhisper(int channelID, string text) 840 public void llWhisper(int channelID, string text)
733 { 841 {
734 m_host.AddScriptLPS(1); 842 m_host.AddScriptLPS(1);
@@ -748,6 +856,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
748 { 856 {
749 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
750 858
859 if (channelID == 0)
860 m_SayShoutCount++;
861
862 if (m_SayShoutCount >= 11)
863 ScriptSleep(2000);
864
751 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 865 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
752 { 866 {
753 Console.WriteLine(text); 867 Console.WriteLine(text);
@@ -770,6 +884,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
770 { 884 {
771 m_host.AddScriptLPS(1); 885 m_host.AddScriptLPS(1);
772 886
887 if (channelID == 0)
888 m_SayShoutCount++;
889
890 if (m_SayShoutCount >= 11)
891 ScriptSleep(2000);
892
773 if (text.Length > 1023) 893 if (text.Length > 1023)
774 text = text.Substring(0, 1023); 894 text = text.Substring(0, 1023);
775 895
@@ -1072,10 +1192,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1072 return detectedParams.TouchUV; 1192 return detectedParams.TouchUV;
1073 } 1193 }
1074 1194
1195 [DebuggerNonUserCode]
1075 public virtual void llDie() 1196 public virtual void llDie()
1076 { 1197 {
1077 m_host.AddScriptLPS(1); 1198 m_host.AddScriptLPS(1);
1078 throw new SelfDeleteException(); 1199 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1079 } 1200 }
1080 1201
1081 public LSL_Float llGround(LSL_Vector offset) 1202 public LSL_Float llGround(LSL_Vector offset)
@@ -1148,6 +1269,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1148 1269
1149 public void llSetStatus(int status, int value) 1270 public void llSetStatus(int status, int value)
1150 { 1271 {
1272 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1273 return;
1151 m_host.AddScriptLPS(1); 1274 m_host.AddScriptLPS(1);
1152 1275
1153 int statusrotationaxis = 0; 1276 int statusrotationaxis = 0;
@@ -1171,6 +1294,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1171 if (!allow) 1294 if (!allow)
1172 return; 1295 return;
1173 1296
1297 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1298 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1299 return;
1300
1174 m_host.ScriptSetPhysicsStatus(true); 1301 m_host.ScriptSetPhysicsStatus(true);
1175 } 1302 }
1176 else 1303 else
@@ -1379,6 +1506,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1379 { 1506 {
1380 m_host.AddScriptLPS(1); 1507 m_host.AddScriptLPS(1);
1381 1508
1509 SetColor(m_host, color, face);
1510 }
1511
1512 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1513 {
1514 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1515 return;
1516
1517 Primitive.TextureEntry tex = part.Shape.Textures;
1518 Color4 texcolor;
1519 if (face >= 0 && face < GetNumberOfSides(part))
1520 {
1521 texcolor = tex.CreateFace((uint)face).RGBA;
1522 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1523 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1524 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1525 tex.FaceTextures[face].RGBA = texcolor;
1526 part.UpdateTextureEntry(tex.GetBytes());
1527 return;
1528 }
1529 else if (face == ScriptBaseClass.ALL_SIDES)
1530 {
1531 for (uint i = 0; i < GetNumberOfSides(part); i++)
1532 {
1533 if (tex.FaceTextures[i] != null)
1534 {
1535 texcolor = tex.FaceTextures[i].RGBA;
1536 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1537 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1538 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1539 tex.FaceTextures[i].RGBA = texcolor;
1540 }
1541 texcolor = tex.DefaultTexture.RGBA;
1542 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1543 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1544 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1545 tex.DefaultTexture.RGBA = texcolor;
1546 }
1547 part.UpdateTextureEntry(tex.GetBytes());
1548 return;
1549 }
1550
1382 if (face == ScriptBaseClass.ALL_SIDES) 1551 if (face == ScriptBaseClass.ALL_SIDES)
1383 face = SceneObjectPart.ALL_SIDES; 1552 face = SceneObjectPart.ALL_SIDES;
1384 1553
@@ -1387,6 +1556,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 1556
1388 public void SetTexGen(SceneObjectPart part, int face,int style) 1557 public void SetTexGen(SceneObjectPart part, int face,int style)
1389 { 1558 {
1559 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1560 return;
1561
1390 Primitive.TextureEntry tex = part.Shape.Textures; 1562 Primitive.TextureEntry tex = part.Shape.Textures;
1391 MappingType textype; 1563 MappingType textype;
1392 textype = MappingType.Default; 1564 textype = MappingType.Default;
@@ -1417,6 +1589,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 1589
1418 public void SetGlow(SceneObjectPart part, int face, float glow) 1590 public void SetGlow(SceneObjectPart part, int face, float glow)
1419 { 1591 {
1592 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1593 return;
1594
1420 Primitive.TextureEntry tex = part.Shape.Textures; 1595 Primitive.TextureEntry tex = part.Shape.Textures;
1421 if (face >= 0 && face < GetNumberOfSides(part)) 1596 if (face >= 0 && face < GetNumberOfSides(part))
1422 { 1597 {
@@ -1442,6 +1617,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 1617
1443 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1618 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1444 { 1619 {
1620 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return;
1445 1622
1446 Shininess sval = new Shininess(); 1623 Shininess sval = new Shininess();
1447 1624
@@ -1492,6 +1669,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 1669
1493 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1670 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1494 { 1671 {
1672 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1673 return;
1674
1495 Primitive.TextureEntry tex = part.Shape.Textures; 1675 Primitive.TextureEntry tex = part.Shape.Textures;
1496 if (face >= 0 && face < GetNumberOfSides(part)) 1676 if (face >= 0 && face < GetNumberOfSides(part))
1497 { 1677 {
@@ -1552,13 +1732,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1552 m_host.AddScriptLPS(1); 1732 m_host.AddScriptLPS(1);
1553 1733
1554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1734 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1555 1735 if (parts.Count > 0)
1556 foreach (SceneObjectPart part in parts) 1736 {
1557 SetAlpha(part, alpha, face); 1737 try
1738 {
1739 parts[0].ParentGroup.areUpdatesSuspended = true;
1740 foreach (SceneObjectPart part in parts)
1741 SetAlpha(part, alpha, face);
1742 }
1743 finally
1744 {
1745 parts[0].ParentGroup.areUpdatesSuspended = false;
1746 }
1747 }
1558 } 1748 }
1559 1749
1560 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1750 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1561 { 1751 {
1752 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1753 return;
1754
1562 Primitive.TextureEntry tex = part.Shape.Textures; 1755 Primitive.TextureEntry tex = part.Shape.Textures;
1563 Color4 texcolor; 1756 Color4 texcolor;
1564 if (face >= 0 && face < GetNumberOfSides(part)) 1757 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1611,7 +1804,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1804 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1612 float wind, float tension, LSL_Vector Force) 1805 float wind, float tension, LSL_Vector Force)
1613 { 1806 {
1614 if (part == null) 1807 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1808 return;
1616 1809
1617 if (flexi) 1810 if (flexi)
@@ -1645,7 +1838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1838 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1839 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1840 {
1648 if (part == null) 1841 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1842 return;
1650 1843
1651 if (light) 1844 if (light)
@@ -1724,15 +1917,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 m_host.AddScriptLPS(1); 1917 m_host.AddScriptLPS(1);
1725 1918
1726 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1919 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1727 1920 if (parts.Count > 0)
1728 foreach (SceneObjectPart part in parts) 1921 {
1729 SetTexture(part, texture, face); 1922 try
1730 1923 {
1924 parts[0].ParentGroup.areUpdatesSuspended = true;
1925 foreach (SceneObjectPart part in parts)
1926 SetTexture(part, texture, face);
1927 }
1928 finally
1929 {
1930 parts[0].ParentGroup.areUpdatesSuspended = false;
1931 }
1932 }
1731 ScriptSleep(200); 1933 ScriptSleep(200);
1732 } 1934 }
1733 1935
1734 protected void SetTexture(SceneObjectPart part, string texture, int face) 1936 protected void SetTexture(SceneObjectPart part, string texture, int face)
1735 { 1937 {
1938 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1939 return;
1940
1736 UUID textureID = new UUID(); 1941 UUID textureID = new UUID();
1737 1942
1738 textureID = InventoryKey(texture, (int)AssetType.Texture); 1943 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1777,6 +1982,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1777 1982
1778 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1983 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1779 { 1984 {
1985 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1986 return;
1987
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1988 Primitive.TextureEntry tex = part.Shape.Textures;
1781 if (face >= 0 && face < GetNumberOfSides(part)) 1989 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 1990 {
@@ -1813,6 +2021,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2021
1814 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2022 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2023 {
2024 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2025 return;
2026
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2027 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2028 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2029 {
@@ -1849,6 +2060,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2060
1850 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2061 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1851 { 2062 {
2063 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2064 return;
2065
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2066 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2067 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2068 {
@@ -1953,26 +2167,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 return real_vec; 2167 return real_vec;
1954 } 2168 }
1955 2169
2170 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2171 {
2172 return new LSL_Integer(SetRegionPos(m_host, pos));
2173 }
2174
2175 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2176 {
2177 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2178 return 0;
2179
2180 SceneObjectGroup grp = part.ParentGroup;
2181
2182 if (grp.IsAttachment)
2183 return 0;
2184
2185 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2186 return 0;
2187
2188 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)
2189 return 0;
2190
2191 float constrainedX = (float)targetPos.x;
2192 float constrainedY = (float)targetPos.y;
2193
2194 if (constrainedX < 0.0f)
2195 constrainedX = 0.0f;
2196 if (constrainedY < 0.0f)
2197 constrainedY = 0.0f;
2198 if (constrainedX >= (float)Constants.RegionSize)
2199 constrainedX = (float)Constants.RegionSize - 0.1f;
2200 if (constrainedY >= (float)Constants.RegionSize)
2201 constrainedY = (float)Constants.RegionSize -0.1f;
2202
2203 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2204
2205 if (targetPos.z < ground)
2206 targetPos.z = ground;
2207
2208 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2209
2210 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2211 return 0;
2212
2213 grp.UpdateGroupPosition(dest);
2214
2215 return 1;
2216 }
2217
1956 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2218 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1957 { 2219 {
1958 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2220 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2221 return;
2222
1959 LSL_Vector currentPos = GetPartLocalPos(part); 2223 LSL_Vector currentPos = GetPartLocalPos(part);
2224 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1960 2225
1961 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1962 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1963 2226
1964 if (part.ParentGroup.RootPart == part) 2227 if (part.ParentGroup.RootPart == part)
1965 { 2228 {
1966 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1967 targetPos.z = ground;
1968 SceneObjectGroup parent = part.ParentGroup; 2229 SceneObjectGroup parent = part.ParentGroup;
1969 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2230 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)); 2231 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2232 return;
2233 Util.FireAndForget(delegate(object x) {
2234 parent.UpdateGroupPosition(dest);
2235 });
1971 } 2236 }
1972 else 2237 else
1973 { 2238 {
1974 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2239 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; 2240 SceneObjectGroup parent = part.ParentGroup;
1977 parent.HasGroupChanged = true; 2241 parent.HasGroupChanged = true;
1978 parent.ScheduleGroupForTerseUpdate(); 2242 parent.ScheduleGroupForTerseUpdate();
@@ -2005,17 +2269,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2005 else 2269 else
2006 { 2270 {
2007 if (part.ParentGroup.IsAttachment) 2271 if (part.ParentGroup.IsAttachment)
2008 {
2009 pos = part.AttachedPos; 2272 pos = part.AttachedPos;
2010 }
2011 else 2273 else
2012 {
2013 pos = part.AbsolutePosition; 2274 pos = part.AbsolutePosition;
2014 }
2015 } 2275 }
2016 2276
2017// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2018
2019 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2277 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2020 } 2278 }
2021 2279
@@ -2024,9 +2282,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 m_host.AddScriptLPS(1); 2282 m_host.AddScriptLPS(1);
2025 2283
2026 // try to let this work as in SL... 2284 // try to let this work as in SL...
2027 if (m_host.ParentID == 0) 2285 if (m_host.LinkNum < 2)
2028 { 2286 {
2029 // special case: If we are root, rotate complete SOG to new rotation 2287 // Special case: If we are root, rotate complete SOG to new
2288 // rotation.
2289 // We are root if the link number is 0 (single prim) or 1
2290 // (root prim). ParentID may be nonzero in attachments and
2291 // using it would cause attachments and HUDs to rotate
2292 // to the wrong positions.
2030 SetRot(m_host, Rot2Quaternion(rot)); 2293 SetRot(m_host, Rot2Quaternion(rot));
2031 } 2294 }
2032 else 2295 else
@@ -2051,6 +2314,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 2314
2052 protected void SetRot(SceneObjectPart part, Quaternion rot) 2315 protected void SetRot(SceneObjectPart part, Quaternion rot)
2053 { 2316 {
2317 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2318 return;
2319
2054 part.UpdateRotation(rot); 2320 part.UpdateRotation(rot);
2055 // Update rotation does not move the object in the physics scene if it's a linkset. 2321 // Update rotation does not move the object in the physics scene if it's a linkset.
2056 2322
@@ -2205,13 +2471,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2205 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2471 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2206 { 2472 {
2207 m_host.AddScriptLPS(1); 2473 m_host.AddScriptLPS(1);
2208 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2474 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2209 } 2475 }
2210 2476
2211 public void llSetTorque(LSL_Vector torque, int local) 2477 public void llSetTorque(LSL_Vector torque, int local)
2212 { 2478 {
2213 m_host.AddScriptLPS(1); 2479 m_host.AddScriptLPS(1);
2214 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2480 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2215 } 2481 }
2216 2482
2217 public LSL_Vector llGetTorque() 2483 public LSL_Vector llGetTorque()
@@ -2241,7 +2507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2241 } 2507 }
2242 else 2508 else
2243 { 2509 {
2244 vel = m_host.Velocity; 2510 vel = m_host.ParentGroup.RootPart.Velocity;
2245 } 2511 }
2246 2512
2247 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2513 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2813,35 +3079,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 public void llLookAt(LSL_Vector target, double strength, double damping) 3079 public void llLookAt(LSL_Vector target, double strength, double damping)
2814 { 3080 {
2815 m_host.AddScriptLPS(1); 3081 m_host.AddScriptLPS(1);
2816 // Determine where we are looking from
2817 LSL_Vector from = llGetPos();
2818 3082
2819 // Work out the normalised vector from the source to the target 3083 // Get the normalized vector to the target
2820 LSL_Vector delta = llVecNorm(target - from); 3084 LSL_Vector d1 = llVecNorm(target - llGetPos());
2821 LSL_Vector angle = new LSL_Vector(0,0,0);
2822 3085
2823 // Calculate the yaw 3086 // Get the bearing (yaw)
2824 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3087 LSL_Vector a1 = new LSL_Vector(0,0,0);
2825 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3088 a1.z = llAtan2(d1.y, d1.x);
2826 3089
2827 // Calculate pitch 3090 // Get the elevation (pitch)
2828 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3091 LSL_Vector a2 = new LSL_Vector(0,0,0);
3092 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2829 3093
2830 // we need to convert from a vector describing 3094 LSL_Rotation r1 = llEuler2Rot(a1);
2831 // the angles of rotation in radians into rotation value 3095 LSL_Rotation r2 = llEuler2Rot(a2);
2832 LSL_Rotation rot = llEuler2Rot(angle); 3096 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 3097
2838 if (strength == 0 || pa == null || !pa.IsPhysical) 3098 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2839 { 3099 {
2840 llSetRot(rot); 3100 // Do nothing if either value is 0 (this has been checked in SL)
3101 if (strength <= 0.0 || damping <= 0.0)
3102 return;
3103
3104 llSetRot(r3 * r2 * r1);
2841 } 3105 }
2842 else 3106 else
2843 { 3107 {
2844 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3108 if (strength == 0)
3109 {
3110 llSetRot(r3 * r2 * r1);
3111 return;
3112 }
3113
3114 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2845 } 3115 }
2846 } 3116 }
2847 3117
@@ -2887,17 +3157,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2887 } 3157 }
2888 else 3158 else
2889 { 3159 {
2890 if (m_host.IsRoot) 3160 // new SL always returns object mass
2891 { 3161// if (m_host.IsRoot)
3162// {
2892 return m_host.ParentGroup.GetMass(); 3163 return m_host.ParentGroup.GetMass();
2893 } 3164// }
2894 else 3165// else
2895 { 3166// {
2896 return m_host.GetMass(); 3167// return m_host.GetMass();
2897 } 3168// }
2898 } 3169 }
2899 } 3170 }
2900 3171
3172
3173 public LSL_Float llGetMassMKS()
3174 {
3175 return 100f * llGetMass();
3176 }
3177
2901 public void llCollisionFilter(string name, string id, int accept) 3178 public void llCollisionFilter(string name, string id, int accept)
2902 { 3179 {
2903 m_host.AddScriptLPS(1); 3180 m_host.AddScriptLPS(1);
@@ -3005,9 +3282,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3005 { 3282 {
3006 m_host.AddScriptLPS(1); 3283 m_host.AddScriptLPS(1);
3007 3284
3008// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3009// return;
3010
3011 if (m_item.PermsGranter != m_host.OwnerID) 3285 if (m_item.PermsGranter != m_host.OwnerID)
3012 return; 3286 return;
3013 3287
@@ -3050,6 +3324,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 3324
3051 public void llInstantMessage(string user, string message) 3325 public void llInstantMessage(string user, string message)
3052 { 3326 {
3327 UUID result;
3328 if (!UUID.TryParse(user, out result))
3329 {
3330 ShoutError("An invalid key was passed to llInstantMessage");
3331 ScriptSleep(2000);
3332 return;
3333 }
3334
3335
3053 m_host.AddScriptLPS(1); 3336 m_host.AddScriptLPS(1);
3054 3337
3055 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3338 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3064,14 +3347,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 UUID friendTransactionID = UUID.Random(); 3347 UUID friendTransactionID = UUID.Random();
3065 3348
3066 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3349 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3067 3350
3068 GridInstantMessage msg = new GridInstantMessage(); 3351 GridInstantMessage msg = new GridInstantMessage();
3069 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3352 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3070 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3353 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3071 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3354 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); 3355// 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()); 3356// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3074 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3357// DateTime dt = DateTime.UtcNow;
3358//
3359// // Ticks from UtcNow, but make it look like local. Evil, huh?
3360// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3361//
3362// try
3363// {
3364// // Convert that to the PST timezone
3365// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3366// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3367// }
3368// catch
3369// {
3370// // No logging here, as it could be VERY spammy
3371// }
3372//
3373// // And make it look local again to fool the unix time util
3374// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3375
3376 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3377
3075 //if (client != null) 3378 //if (client != null)
3076 //{ 3379 //{
3077 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3380 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3085,12 +3388,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3085 msg.message = message.Substring(0, 1024); 3388 msg.message = message.Substring(0, 1024);
3086 else 3389 else
3087 msg.message = message; 3390 msg.message = message;
3088 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3391 msg.dialog = (byte)19; // MessageFromObject
3089 msg.fromGroup = false;// fromGroup; 3392 msg.fromGroup = false;// fromGroup;
3090 msg.offline = (byte)0; //offline; 3393 msg.offline = (byte)0; //offline;
3091 msg.ParentEstateID = 0; //ParentEstateID; 3394 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3092 msg.Position = new Vector3(m_host.AbsolutePosition); 3395 msg.Position = new Vector3(m_host.AbsolutePosition);
3093 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3396 msg.RegionID = World.RegionInfo.RegionID.Guid;
3094 msg.binaryBucket 3397 msg.binaryBucket
3095 = Util.StringToBytes256( 3398 = Util.StringToBytes256(
3096 "{0}/{1}/{2}/{3}", 3399 "{0}/{1}/{2}/{3}",
@@ -3118,7 +3421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3118 } 3421 }
3119 3422
3120 emailModule.SendEmail(m_host.UUID, address, subject, message); 3423 emailModule.SendEmail(m_host.UUID, address, subject, message);
3121 llSleep(EMAIL_PAUSE_TIME); 3424 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3122 } 3425 }
3123 3426
3124 public void llGetNextEmail(string address, string subject) 3427 public void llGetNextEmail(string address, string subject)
@@ -3362,15 +3665,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3362 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3665 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3363 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3666 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3364 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3667 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3668 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3365 ScriptBaseClass.PERMISSION_ATTACH; 3669 ScriptBaseClass.PERMISSION_ATTACH;
3366 3670
3367 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3671 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3368 { 3672 {
3369 lock (m_host.TaskInventory) 3673 m_host.TaskInventory.LockItemsForWrite(true);
3370 { 3674 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3371 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3675 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3372 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3676 m_host.TaskInventory.LockItemsForWrite(false);
3373 }
3374 3677
3375 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3678 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3376 "run_time_permissions", new Object[] { 3679 "run_time_permissions", new Object[] {
@@ -3380,28 +3683,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3380 return; 3683 return;
3381 } 3684 }
3382 } 3685 }
3383 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3686 else
3384 { 3687 {
3385 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3688 bool sitting = false;
3386 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3689 if (m_host.SitTargetAvatar == agentID)
3387 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3690 {
3388 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3691 sitting = true;
3389 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3692 }
3693 else
3694 {
3695 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3696 {
3697 if (p.SitTargetAvatar == agentID)
3698 sitting = true;
3699 }
3700 }
3390 3701
3391 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3702 if (sitting)
3392 { 3703 {
3393 lock (m_host.TaskInventory) 3704 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3705 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3706 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3707 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3708 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3709
3710 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3394 { 3711 {
3712 m_host.TaskInventory.LockItemsForWrite(true);
3395 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3713 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3396 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3714 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3397 } 3715 m_host.TaskInventory.LockItemsForWrite(false);
3398 3716
3399 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3717 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3400 "run_time_permissions", new Object[] { 3718 "run_time_permissions", new Object[] {
3401 new LSL_Integer(perm) }, 3719 new LSL_Integer(perm) },
3402 new DetectParams[0])); 3720 new DetectParams[0]));
3403 3721
3404 return; 3722 return;
3723 }
3405 } 3724 }
3406 } 3725 }
3407 3726
@@ -3438,11 +3757,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 3757
3439 if (!m_waitingForScriptAnswer) 3758 if (!m_waitingForScriptAnswer)
3440 { 3759 {
3441 lock (m_host.TaskInventory) 3760 m_host.TaskInventory.LockItemsForWrite(true);
3442 { 3761 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3443 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3762 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3444 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3763 m_host.TaskInventory.LockItemsForWrite(false);
3445 }
3446 3764
3447 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3765 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3448 m_waitingForScriptAnswer=true; 3766 m_waitingForScriptAnswer=true;
@@ -3471,14 +3789,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3789 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3472 llReleaseControls(); 3790 llReleaseControls();
3473 3791
3474 lock (m_host.TaskInventory) 3792 m_host.TaskInventory.LockItemsForWrite(true);
3475 { 3793 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3476 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3794 m_host.TaskInventory.LockItemsForWrite(false);
3477 } 3795
3478 3796 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3479 m_ScriptEngine.PostScriptEvent( 3797 "run_time_permissions", new Object[] {
3480 m_item.ItemID, 3798 new LSL_Integer(answer) },
3481 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3799 new DetectParams[0]));
3482 } 3800 }
3483 3801
3484 public LSL_String llGetPermissionsKey() 3802 public LSL_String llGetPermissionsKey()
@@ -3517,14 +3835,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3835 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3518 { 3836 {
3519 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3837 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3520 3838 if (parts.Count > 0)
3521 foreach (SceneObjectPart part in parts) 3839 {
3522 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3840 try
3841 {
3842 parts[0].ParentGroup.areUpdatesSuspended = true;
3843 foreach (SceneObjectPart part in parts)
3844 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3845 }
3846 finally
3847 {
3848 parts[0].ParentGroup.areUpdatesSuspended = false;
3849 }
3850 }
3523 } 3851 }
3524 3852
3525 public void llCreateLink(string target, int parent) 3853 public void llCreateLink(string target, int parent)
3526 { 3854 {
3527 m_host.AddScriptLPS(1); 3855 m_host.AddScriptLPS(1);
3856
3528 UUID targetID; 3857 UUID targetID;
3529 3858
3530 if (!UUID.TryParse(target, out targetID)) 3859 if (!UUID.TryParse(target, out targetID))
@@ -3630,10 +3959,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3630 // Restructuring Multiple Prims. 3959 // Restructuring Multiple Prims.
3631 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3960 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3632 parts.Remove(parentPrim.RootPart); 3961 parts.Remove(parentPrim.RootPart);
3633 foreach (SceneObjectPart part in parts) 3962 if (parts.Count > 0)
3634 { 3963 {
3635 parentPrim.DelinkFromGroup(part.LocalId, true); 3964 try
3965 {
3966 parts[0].ParentGroup.areUpdatesSuspended = true;
3967 foreach (SceneObjectPart part in parts)
3968 {
3969 parentPrim.DelinkFromGroup(part.LocalId, true);
3970 }
3971 }
3972 finally
3973 {
3974 parts[0].ParentGroup.areUpdatesSuspended = false;
3975 }
3636 } 3976 }
3977
3637 parentPrim.HasGroupChanged = true; 3978 parentPrim.HasGroupChanged = true;
3638 parentPrim.ScheduleGroupForFullUpdate(); 3979 parentPrim.ScheduleGroupForFullUpdate();
3639 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3980 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3642,12 +3983,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3642 { 3983 {
3643 SceneObjectPart newRoot = parts[0]; 3984 SceneObjectPart newRoot = parts[0];
3644 parts.Remove(newRoot); 3985 parts.Remove(newRoot);
3645 foreach (SceneObjectPart part in parts) 3986
3987 try
3646 { 3988 {
3647 // Required for linking 3989 parts[0].ParentGroup.areUpdatesSuspended = true;
3648 part.ClearUpdateSchedule(); 3990 foreach (SceneObjectPart part in parts)
3649 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3991 {
3992 part.ClearUpdateSchedule();
3993 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3994 }
3650 } 3995 }
3996 finally
3997 {
3998 parts[0].ParentGroup.areUpdatesSuspended = false;
3999 }
4000
4001
3651 newRoot.ParentGroup.HasGroupChanged = true; 4002 newRoot.ParentGroup.HasGroupChanged = true;
3652 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4003 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3653 } 4004 }
@@ -3667,6 +4018,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3667 public void llBreakAllLinks() 4018 public void llBreakAllLinks()
3668 { 4019 {
3669 m_host.AddScriptLPS(1); 4020 m_host.AddScriptLPS(1);
4021
4022 TaskInventoryItem item = m_item;
4023
4024 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4025 && !m_automaticLinkPermission)
4026 {
4027 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4028 return;
4029 }
4030
3670 SceneObjectGroup parentPrim = m_host.ParentGroup; 4031 SceneObjectGroup parentPrim = m_host.ParentGroup;
3671 if (parentPrim.AttachmentPoint != 0) 4032 if (parentPrim.AttachmentPoint != 0)
3672 return; // Fail silently if attached 4033 return; // Fail silently if attached
@@ -3686,25 +4047,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 public LSL_String llGetLinkKey(int linknum) 4047 public LSL_String llGetLinkKey(int linknum)
3687 { 4048 {
3688 m_host.AddScriptLPS(1); 4049 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); 4050 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3709 if (part != null) 4051 if (part != null)
3710 { 4052 {
@@ -3712,6 +4054,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3712 } 4054 }
3713 else 4055 else
3714 { 4056 {
4057 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4058 {
4059 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4060
4061 if (linknum < 0)
4062 return UUID.Zero.ToString();
4063
4064 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4065 if (avatars.Count > linknum)
4066 {
4067 return avatars[linknum].UUID.ToString();
4068 }
4069 }
3715 return UUID.Zero.ToString(); 4070 return UUID.Zero.ToString();
3716 } 4071 }
3717 } 4072 }
@@ -3811,17 +4166,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3811 m_host.AddScriptLPS(1); 4166 m_host.AddScriptLPS(1);
3812 int count = 0; 4167 int count = 0;
3813 4168
3814 lock (m_host.TaskInventory) 4169 m_host.TaskInventory.LockItemsForRead(true);
4170 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3815 { 4171 {
3816 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4172 if (inv.Value.Type == type || type == -1)
3817 { 4173 {
3818 if (inv.Value.Type == type || type == -1) 4174 count = count + 1;
3819 {
3820 count = count + 1;
3821 }
3822 } 4175 }
3823 } 4176 }
3824 4177
4178 m_host.TaskInventory.LockItemsForRead(false);
3825 return count; 4179 return count;
3826 } 4180 }
3827 4181
@@ -3830,16 +4184,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3830 m_host.AddScriptLPS(1); 4184 m_host.AddScriptLPS(1);
3831 ArrayList keys = new ArrayList(); 4185 ArrayList keys = new ArrayList();
3832 4186
3833 lock (m_host.TaskInventory) 4187 m_host.TaskInventory.LockItemsForRead(true);
4188 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3834 { 4189 {
3835 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4190 if (inv.Value.Type == type || type == -1)
3836 { 4191 {
3837 if (inv.Value.Type == type || type == -1) 4192 keys.Add(inv.Value.Name);
3838 {
3839 keys.Add(inv.Value.Name);
3840 }
3841 } 4193 }
3842 } 4194 }
4195 m_host.TaskInventory.LockItemsForRead(false);
3843 4196
3844 if (keys.Count == 0) 4197 if (keys.Count == 0)
3845 { 4198 {
@@ -3876,25 +4229,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3876 } 4229 }
3877 4230
3878 // move the first object found with this inventory name 4231 // move the first object found with this inventory name
3879 lock (m_host.TaskInventory) 4232 m_host.TaskInventory.LockItemsForRead(true);
4233 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3880 { 4234 {
3881 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4235 if (inv.Value.Name == inventory)
3882 { 4236 {
3883 if (inv.Value.Name == inventory) 4237 found = true;
3884 { 4238 objId = inv.Key;
3885 found = true; 4239 assetType = inv.Value.Type;
3886 objId = inv.Key; 4240 objName = inv.Value.Name;
3887 assetType = inv.Value.Type; 4241 break;
3888 objName = inv.Value.Name;
3889 break;
3890 }
3891 } 4242 }
3892 } 4243 }
4244 m_host.TaskInventory.LockItemsForRead(false);
3893 4245
3894 if (!found) 4246 if (!found)
3895 { 4247 {
3896 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4248 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)); 4249 return;
4250// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3898 } 4251 }
3899 4252
3900 // check if destination is an object 4253 // check if destination is an object
@@ -3920,48 +4273,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3920 return; 4273 return;
3921 } 4274 }
3922 } 4275 }
4276
3923 // destination is an avatar 4277 // destination is an avatar
3924 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4278 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3925 4279
3926 if (agentItem == null) 4280 if (agentItem == null)
3927 return; 4281 return;
3928 4282
3929 byte[] bucket = new byte[17]; 4283 byte[] bucket = new byte[1];
3930 bucket[0] = (byte)assetType; 4284 bucket[0] = (byte)assetType;
3931 byte[] objBytes = agentItem.ID.GetBytes(); 4285 //byte[] objBytes = agentItem.ID.GetBytes();
3932 Array.Copy(objBytes, 0, bucket, 1, 16); 4286 //Array.Copy(objBytes, 0, bucket, 1, 16);
3933 4287
3934 GridInstantMessage msg = new GridInstantMessage(World, 4288 GridInstantMessage msg = new GridInstantMessage(World,
3935 m_host.UUID, m_host.Name+", an object owned by "+ 4289 m_host.OwnerID, m_host.Name, destId,
3936 resolveName(m_host.OwnerID)+",", destId,
3937 (byte)InstantMessageDialog.TaskInventoryOffered, 4290 (byte)InstantMessageDialog.TaskInventoryOffered,
3938 false, objName+"\n"+m_host.Name+" is located at "+ 4291 false, objName+". "+m_host.Name+" is located at "+
3939 World.RegionInfo.RegionName+" "+ 4292 World.RegionInfo.RegionName+" "+
3940 m_host.AbsolutePosition.ToString(), 4293 m_host.AbsolutePosition.ToString(),
3941 agentItem.ID, true, m_host.AbsolutePosition, 4294 agentItem.ID, true, m_host.AbsolutePosition,
3942 bucket); 4295 bucket);
3943 if (m_TransferModule != null) 4296
3944 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4297 ScenePresence sp;
4298
4299 if (World.TryGetScenePresence(destId, out sp))
4300 {
4301 sp.ControllingClient.SendInstantMessage(msg);
4302 }
4303 else
4304 {
4305 if (m_TransferModule != null)
4306 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4307 }
4308
4309 //This delay should only occur when giving inventory to avatars.
3945 ScriptSleep(3000); 4310 ScriptSleep(3000);
3946 } 4311 }
3947 } 4312 }
3948 4313
4314 [DebuggerNonUserCode]
3949 public void llRemoveInventory(string name) 4315 public void llRemoveInventory(string name)
3950 { 4316 {
3951 m_host.AddScriptLPS(1); 4317 m_host.AddScriptLPS(1);
3952 4318
3953 lock (m_host.TaskInventory) 4319 List<TaskInventoryItem> inv;
4320 try
3954 { 4321 {
3955 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4322 m_host.TaskInventory.LockItemsForRead(true);
4323 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4324 }
4325 finally
4326 {
4327 m_host.TaskInventory.LockItemsForRead(false);
4328 }
4329 foreach (TaskInventoryItem item in inv)
4330 {
4331 if (item.Name == name)
3956 { 4332 {
3957 if (item.Name == name) 4333 if (item.ItemID == m_item.ItemID)
3958 { 4334 throw new ScriptDeleteException();
3959 if (item.ItemID == m_item.ItemID) 4335 else
3960 throw new ScriptDeleteException(); 4336 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3961 else 4337 return;
3962 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3963 return;
3964 }
3965 } 4338 }
3966 } 4339 }
3967 } 4340 }
@@ -3996,115 +4369,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3996 { 4369 {
3997 m_host.AddScriptLPS(1); 4370 m_host.AddScriptLPS(1);
3998 4371
3999 UUID uuid = (UUID)id; 4372 UUID uuid;
4000 PresenceInfo pinfo = null; 4373 if (UUID.TryParse(id, out uuid))
4001 UserAccount account;
4002
4003 UserInfoCacheEntry ce;
4004 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4005 { 4374 {
4006 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4375 PresenceInfo pinfo = null;
4007 if (account == null) 4376 UserAccount account;
4377
4378 UserInfoCacheEntry ce;
4379 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4008 { 4380 {
4009 m_userInfoCache[uuid] = null; // Cache negative 4381 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4010 return UUID.Zero.ToString(); 4382 if (account == null)
4011 } 4383 {
4384 m_userInfoCache[uuid] = null; // Cache negative
4385 return UUID.Zero.ToString();
4386 }
4012 4387
4013 4388
4014 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4389 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4015 if (pinfos != null && pinfos.Length > 0) 4390 if (pinfos != null && pinfos.Length > 0)
4016 {
4017 foreach (PresenceInfo p in pinfos)
4018 { 4391 {
4019 if (p.RegionID != UUID.Zero) 4392 foreach (PresenceInfo p in pinfos)
4020 { 4393 {
4021 pinfo = p; 4394 if (p.RegionID != UUID.Zero)
4395 {
4396 pinfo = p;
4397 }
4022 } 4398 }
4023 } 4399 }
4024 }
4025 4400
4026 ce = new UserInfoCacheEntry(); 4401 ce = new UserInfoCacheEntry();
4027 ce.time = Util.EnvironmentTickCount(); 4402 ce.time = Util.EnvironmentTickCount();
4028 ce.account = account; 4403 ce.account = account;
4029 ce.pinfo = pinfo; 4404 ce.pinfo = pinfo;
4030 } 4405 m_userInfoCache[uuid] = ce;
4031 else 4406 }
4032 { 4407 else
4033 if (ce == null) 4408 {
4034 return UUID.Zero.ToString(); 4409 if (ce == null)
4410 return UUID.Zero.ToString();
4035 4411
4036 account = ce.account; 4412 account = ce.account;
4037 pinfo = ce.pinfo; 4413 pinfo = ce.pinfo;
4038 } 4414 }
4039 4415
4040 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4416 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 { 4417 {
4045 foreach (PresenceInfo p in pinfos) 4418 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4419 if (pinfos != null && pinfos.Length > 0)
4046 { 4420 {
4047 if (p.RegionID != UUID.Zero) 4421 foreach (PresenceInfo p in pinfos)
4048 { 4422 {
4049 pinfo = p; 4423 if (p.RegionID != UUID.Zero)
4424 {
4425 pinfo = p;
4426 }
4050 } 4427 }
4051 } 4428 }
4052 } 4429 else
4053 else 4430 pinfo = null;
4054 pinfo = null;
4055 4431
4056 ce.time = Util.EnvironmentTickCount(); 4432 ce.time = Util.EnvironmentTickCount();
4057 ce.pinfo = pinfo; 4433 ce.pinfo = pinfo;
4058 } 4434 }
4059 4435
4060 string reply = String.Empty; 4436 string reply = String.Empty;
4061 4437
4062 switch (data) 4438 switch (data)
4063 { 4439 {
4064 case 1: // DATA_ONLINE (0|1) 4440 case 1: // DATA_ONLINE (0|1)
4065 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4441 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4066 reply = "1"; 4442 reply = "1";
4067 else 4443 else
4068 reply = "0"; 4444 reply = "0";
4069 break; 4445 break;
4070 case 2: // DATA_NAME (First Last) 4446 case 2: // DATA_NAME (First Last)
4071 reply = account.FirstName + " " + account.LastName; 4447 reply = account.FirstName + " " + account.LastName;
4072 break; 4448 break;
4073 case 3: // DATA_BORN (YYYY-MM-DD) 4449 case 3: // DATA_BORN (YYYY-MM-DD)
4074 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4450 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4075 born = born.AddSeconds(account.Created); 4451 born = born.AddSeconds(account.Created);
4076 reply = born.ToString("yyyy-MM-dd"); 4452 reply = born.ToString("yyyy-MM-dd");
4077 break; 4453 break;
4078 case 4: // DATA_RATING (0,0,0,0,0,0) 4454 case 4: // DATA_RATING (0,0,0,0,0,0)
4079 reply = "0,0,0,0,0,0"; 4455 reply = "0,0,0,0,0,0";
4080 break; 4456 break;
4081 case 7: // DATA_USERLEVEL (integer) 4457 case 8: // DATA_PAYINFO (0|1|2|3)
4082 reply = account.UserLevel.ToString(); 4458 reply = "0";
4083 break; 4459 break;
4084 case 8: // DATA_PAYINFO (0|1|2|3) 4460 default:
4085 reply = "0"; 4461 return UUID.Zero.ToString(); // Raise no event
4086 break; 4462 }
4087 default:
4088 return UUID.Zero.ToString(); // Raise no event
4089 }
4090 4463
4091 UUID rq = UUID.Random(); 4464 UUID rq = UUID.Random();
4092 4465
4093 UUID tid = AsyncCommands. 4466 UUID tid = AsyncCommands.
4094 DataserverPlugin.RegisterRequest(m_host.LocalId, 4467 DataserverPlugin.RegisterRequest(m_host.LocalId,
4095 m_item.ItemID, rq.ToString()); 4468 m_item.ItemID, rq.ToString());
4096 4469
4097 AsyncCommands. 4470 AsyncCommands.
4098 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4471 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4099 4472
4100 ScriptSleep(100); 4473 ScriptSleep(100);
4101 return tid.ToString(); 4474 return tid.ToString();
4475 }
4476 else
4477 {
4478 ShoutError("Invalid UUID passed to llRequestAgentData.");
4479 }
4480 return "";
4102 } 4481 }
4103 4482
4104 public LSL_String llRequestInventoryData(string name) 4483 public LSL_String llRequestInventoryData(string name)
4105 { 4484 {
4106 m_host.AddScriptLPS(1); 4485 m_host.AddScriptLPS(1);
4107 4486
4487 //Clone is thread safe
4108 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4488 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4109 4489
4110 foreach (TaskInventoryItem item in itemDictionary.Values) 4490 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4156,19 +4536,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4156 if (UUID.TryParse(agent, out agentId)) 4536 if (UUID.TryParse(agent, out agentId))
4157 { 4537 {
4158 ScenePresence presence = World.GetScenePresence(agentId); 4538 ScenePresence presence = World.GetScenePresence(agentId);
4159 if (presence != null) 4539 if (presence != null && presence.PresenceType != PresenceType.Npc)
4160 { 4540 {
4541 // agent must not be a god
4542 if (presence.UserLevel >= 200) return;
4543
4161 // agent must be over the owners land 4544 // agent must be over the owners land
4162 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4545 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4163 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4546 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4164 { 4547 {
4165 World.TeleportClientHome(agentId, presence.ControllingClient); 4548 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4549 {
4550 // They can't be teleported home for some reason
4551 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4552 if (regionInfo != null)
4553 {
4554 World.RequestTeleportLocation(
4555 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4556 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4557 }
4558 }
4166 } 4559 }
4167 } 4560 }
4168 } 4561 }
4169 ScriptSleep(5000); 4562 ScriptSleep(5000);
4170 } 4563 }
4171 4564
4565 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4566 {
4567 m_host.AddScriptLPS(1);
4568 UUID agentId = new UUID();
4569 if (UUID.TryParse(agent, out agentId))
4570 {
4571 ScenePresence presence = World.GetScenePresence(agentId);
4572 if (presence != null && presence.PresenceType != PresenceType.Npc)
4573 {
4574 // agent must not be a god
4575 if (presence.GodLevel >= 200) return;
4576
4577 if (simname == String.Empty)
4578 simname = World.RegionInfo.RegionName;
4579
4580 // agent must be over the owners land
4581 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4582 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4583 {
4584 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);
4585 }
4586 else // or must be wearing the prim
4587 {
4588 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4589 {
4590 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);
4591 }
4592 }
4593 }
4594 }
4595 }
4596
4172 public void llTextBox(string agent, string message, int chatChannel) 4597 public void llTextBox(string agent, string message, int chatChannel)
4173 { 4598 {
4174 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4599 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4180,7 +4605,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4180 UUID av = new UUID(); 4605 UUID av = new UUID();
4181 if (!UUID.TryParse(agent,out av)) 4606 if (!UUID.TryParse(agent,out av))
4182 { 4607 {
4183 LSLError("First parameter to llDialog needs to be a key"); 4608 //LSLError("First parameter to llDialog needs to be a key");
4184 return; 4609 return;
4185 } 4610 }
4186 4611
@@ -4212,25 +4637,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4212 public void llCollisionSound(string impact_sound, double impact_volume) 4637 public void llCollisionSound(string impact_sound, double impact_volume)
4213 { 4638 {
4214 m_host.AddScriptLPS(1); 4639 m_host.AddScriptLPS(1);
4215 4640
4641 if(impact_sound == "")
4642 {
4643 m_host.CollisionSoundVolume = (float)impact_volume;
4644 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4645 return;
4646 }
4216 // TODO: Parameter check logic required. 4647 // TODO: Parameter check logic required.
4217 UUID soundId = UUID.Zero; 4648 UUID soundId = UUID.Zero;
4218 if (!UUID.TryParse(impact_sound, out soundId)) 4649 if (!UUID.TryParse(impact_sound, out soundId))
4219 { 4650 {
4220 lock (m_host.TaskInventory) 4651 m_host.TaskInventory.LockItemsForRead(true);
4652 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4221 { 4653 {
4222 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4654 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4223 { 4655 {
4224 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4656 soundId = item.AssetID;
4225 { 4657 break;
4226 soundId = item.AssetID;
4227 break;
4228 }
4229 } 4658 }
4230 } 4659 }
4660 m_host.TaskInventory.LockItemsForRead(false);
4231 } 4661 }
4232 m_host.CollisionSound = soundId;
4233 m_host.CollisionSoundVolume = (float)impact_volume; 4662 m_host.CollisionSoundVolume = (float)impact_volume;
4663 m_host.CollisionSound = soundId;
4234 } 4664 }
4235 4665
4236 public LSL_String llGetAnimation(string id) 4666 public LSL_String llGetAnimation(string id)
@@ -4244,14 +4674,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 4674
4245 if (m_host.RegionHandle == presence.RegionHandle) 4675 if (m_host.RegionHandle == presence.RegionHandle)
4246 { 4676 {
4247 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4248
4249 if (presence != null) 4677 if (presence != null)
4250 { 4678 {
4251 AnimationSet currentAnims = presence.Animator.Animations; 4679 if (presence.SitGround)
4252 string currentAnimationState = String.Empty; 4680 return "Sitting on Ground";
4253 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4681 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4254 return currentAnimationState; 4682 return "Sitting";
4683
4684 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4685 string lslMovementAnimation;
4686
4687 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4688 return lslMovementAnimation;
4255 } 4689 }
4256 } 4690 }
4257 4691
@@ -4267,6 +4701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4267 UUID partItemID; 4701 UUID partItemID;
4268 foreach (SceneObjectPart part in parts) 4702 foreach (SceneObjectPart part in parts)
4269 { 4703 {
4704 //Clone is thread safe
4270 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4705 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4271 4706
4272 foreach (TaskInventoryItem item in itemsDictionary.Values) 4707 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4400,7 +4835,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4400 { 4835 {
4401 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4836 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4402 float distance_term = distance * distance * distance; // Script Energy 4837 float distance_term = distance * distance * distance; // Script Energy
4403 float pusher_mass = m_host.GetMass(); 4838 // use total object mass and not part
4839 float pusher_mass = m_host.ParentGroup.GetMass();
4404 4840
4405 float PUSH_ATTENUATION_DISTANCE = 17f; 4841 float PUSH_ATTENUATION_DISTANCE = 17f;
4406 float PUSH_ATTENUATION_SCALE = 5f; 4842 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4639,23 +5075,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4639 { 5075 {
4640 m_host.AddScriptLPS(1); 5076 m_host.AddScriptLPS(1);
4641 5077
4642 lock (m_host.TaskInventory) 5078 m_host.TaskInventory.LockItemsForRead(true);
5079 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4643 { 5080 {
4644 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5081 if (inv.Value.Name == name)
4645 { 5082 {
4646 if (inv.Value.Name == name) 5083 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4647 { 5084 {
4648 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5085 m_host.TaskInventory.LockItemsForRead(false);
4649 { 5086 return inv.Value.AssetID.ToString();
4650 return inv.Value.AssetID.ToString(); 5087 }
4651 } 5088 else
4652 else 5089 {
4653 { 5090 m_host.TaskInventory.LockItemsForRead(false);
4654 return UUID.Zero.ToString(); 5091 return UUID.Zero.ToString();
4655 }
4656 } 5092 }
4657 } 5093 }
4658 } 5094 }
5095 m_host.TaskInventory.LockItemsForRead(false);
4659 5096
4660 return UUID.Zero.ToString(); 5097 return UUID.Zero.ToString();
4661 } 5098 }
@@ -4789,7 +5226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4789 public LSL_Vector llGetCenterOfMass() 5226 public LSL_Vector llGetCenterOfMass()
4790 { 5227 {
4791 m_host.AddScriptLPS(1); 5228 m_host.AddScriptLPS(1);
4792 Vector3 center = m_host.GetGeometricCenter(); 5229 Vector3 center = m_host.GetCenterOfMass();
4793 return new LSL_Vector(center.X,center.Y,center.Z); 5230 return new LSL_Vector(center.X,center.Y,center.Z);
4794 } 5231 }
4795 5232
@@ -4808,14 +5245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4808 { 5245 {
4809 m_host.AddScriptLPS(1); 5246 m_host.AddScriptLPS(1);
4810 5247
4811 if (src == null) 5248 return src.Length;
4812 {
4813 return 0;
4814 }
4815 else
4816 {
4817 return src.Length;
4818 }
4819 } 5249 }
4820 5250
4821 public LSL_Integer llList2Integer(LSL_List src, int index) 5251 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4861,7 +5291,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4861 else if (src.Data[index] is LSL_Float) 5291 else if (src.Data[index] is LSL_Float)
4862 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5292 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4863 else if (src.Data[index] is LSL_String) 5293 else if (src.Data[index] is LSL_String)
4864 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5294 {
5295 string str = ((LSL_String) src.Data[index]).m_string;
5296 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5297 if (m != Match.Empty)
5298 {
5299 str = m.Value;
5300 double d = 0.0;
5301 if (!Double.TryParse(str, out d))
5302 return 0.0;
5303
5304 return d;
5305 }
5306 return 0.0;
5307 }
4865 return Convert.ToDouble(src.Data[index]); 5308 return Convert.ToDouble(src.Data[index]);
4866 } 5309 }
4867 catch (FormatException) 5310 catch (FormatException)
@@ -5134,7 +5577,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5134 } 5577 }
5135 } 5578 }
5136 } 5579 }
5137 else { 5580 else
5581 {
5138 object[] array = new object[src.Length]; 5582 object[] array = new object[src.Length];
5139 Array.Copy(src.Data, 0, array, 0, src.Length); 5583 Array.Copy(src.Data, 0, array, 0, src.Length);
5140 result = new LSL_List(array); 5584 result = new LSL_List(array);
@@ -5241,7 +5685,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5241 public LSL_Integer llGetRegionAgentCount() 5685 public LSL_Integer llGetRegionAgentCount()
5242 { 5686 {
5243 m_host.AddScriptLPS(1); 5687 m_host.AddScriptLPS(1);
5244 return new LSL_Integer(World.GetRootAgentCount()); 5688
5689 int count = 0;
5690 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5691 count++;
5692 });
5693
5694 return new LSL_Integer(count);
5245 } 5695 }
5246 5696
5247 public LSL_Vector llGetRegionCorner() 5697 public LSL_Vector llGetRegionCorner()
@@ -5521,6 +5971,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5521 flags |= ScriptBaseClass.AGENT_SITTING; 5971 flags |= ScriptBaseClass.AGENT_SITTING;
5522 } 5972 }
5523 5973
5974 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
5975 {
5976 flags |= ScriptBaseClass.AGENT_MALE;
5977 }
5978
5524 return flags; 5979 return flags;
5525 } 5980 }
5526 5981
@@ -5668,10 +6123,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5668 m_host.AddScriptLPS(1); 6123 m_host.AddScriptLPS(1);
5669 6124
5670 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6125 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5671 6126 if (parts.Count > 0)
5672 foreach (var part in parts)
5673 { 6127 {
5674 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6128 try
6129 {
6130 parts[0].ParentGroup.areUpdatesSuspended = true;
6131 foreach (var part in parts)
6132 {
6133 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6134 }
6135 }
6136 finally
6137 {
6138 parts[0].ParentGroup.areUpdatesSuspended = false;
6139 }
5675 } 6140 }
5676 } 6141 }
5677 6142
@@ -5723,13 +6188,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5723 6188
5724 if (m_host.OwnerID == land.LandData.OwnerID) 6189 if (m_host.OwnerID == land.LandData.OwnerID)
5725 { 6190 {
5726 World.TeleportClientHome(agentID, presence.ControllingClient); 6191 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6192 presence.TeleportWithMomentum(pos, null);
6193 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5727 } 6194 }
5728 } 6195 }
5729 } 6196 }
5730 ScriptSleep(5000); 6197 ScriptSleep(5000);
5731 } 6198 }
5732 6199
6200 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6201 {
6202 return ParseString2List(str, separators, in_spacers, false);
6203 }
6204
5733 public LSL_Integer llOverMyLand(string id) 6205 public LSL_Integer llOverMyLand(string id)
5734 { 6206 {
5735 m_host.AddScriptLPS(1); 6207 m_host.AddScriptLPS(1);
@@ -5794,8 +6266,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5794 UUID agentId = new UUID(); 6266 UUID agentId = new UUID();
5795 if (!UUID.TryParse(agent, out agentId)) 6267 if (!UUID.TryParse(agent, out agentId))
5796 return new LSL_Integer(0); 6268 return new LSL_Integer(0);
6269 if (agentId == m_host.GroupID)
6270 return new LSL_Integer(1);
5797 ScenePresence presence = World.GetScenePresence(agentId); 6271 ScenePresence presence = World.GetScenePresence(agentId);
5798 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6272 if (presence == null || presence.IsChildAgent) // Return false for child agents
5799 return new LSL_Integer(0); 6273 return new LSL_Integer(0);
5800 IClientAPI client = presence.ControllingClient; 6274 IClientAPI client = presence.ControllingClient;
5801 if (m_host.GroupID == client.ActiveGroupId) 6275 if (m_host.GroupID == client.ActiveGroupId)
@@ -5930,7 +6404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5930 return m_host.ParentGroup.AttachmentPoint; 6404 return m_host.ParentGroup.AttachmentPoint;
5931 } 6405 }
5932 6406
5933 public LSL_Integer llGetFreeMemory() 6407 public virtual LSL_Integer llGetFreeMemory()
5934 { 6408 {
5935 m_host.AddScriptLPS(1); 6409 m_host.AddScriptLPS(1);
5936 // Make scripts designed for LSO happy 6410 // Make scripts designed for LSO happy
@@ -6047,7 +6521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6047 SetParticleSystem(m_host, rules); 6521 SetParticleSystem(m_host, rules);
6048 } 6522 }
6049 6523
6050 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6524 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6525 {
6051 6526
6052 6527
6053 if (rules.Length == 0) 6528 if (rules.Length == 0)
@@ -6241,14 +6716,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6241 6716
6242 protected UUID GetTaskInventoryItem(string name) 6717 protected UUID GetTaskInventoryItem(string name)
6243 { 6718 {
6244 lock (m_host.TaskInventory) 6719 m_host.TaskInventory.LockItemsForRead(true);
6720 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6245 { 6721 {
6246 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6722 if (inv.Value.Name == name)
6247 { 6723 {
6248 if (inv.Value.Name == name) 6724 m_host.TaskInventory.LockItemsForRead(false);
6249 return inv.Key; 6725 return inv.Key;
6250 } 6726 }
6251 } 6727 }
6728 m_host.TaskInventory.LockItemsForRead(false);
6252 6729
6253 return UUID.Zero; 6730 return UUID.Zero;
6254 } 6731 }
@@ -6286,16 +6763,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6286 if (folderID == UUID.Zero) 6763 if (folderID == UUID.Zero)
6287 return; 6764 return;
6288 6765
6289 byte[] bucket = new byte[17]; 6766 byte[] bucket = new byte[1];
6290 bucket[0] = (byte)AssetType.Folder; 6767 bucket[0] = (byte)AssetType.Folder;
6291 byte[] objBytes = folderID.GetBytes(); 6768 //byte[] objBytes = folderID.GetBytes();
6292 Array.Copy(objBytes, 0, bucket, 1, 16); 6769 //Array.Copy(objBytes, 0, bucket, 1, 16);
6293 6770
6294 GridInstantMessage msg = new GridInstantMessage(World, 6771 GridInstantMessage msg = new GridInstantMessage(World,
6295 m_host.UUID, m_host.Name+", an object owned by "+ 6772 m_host.OwnerID, m_host.Name, destID,
6296 resolveName(m_host.OwnerID)+",", destID, 6773 (byte)InstantMessageDialog.TaskInventoryOffered,
6297 (byte)InstantMessageDialog.InventoryOffered, 6774 false, category+". "+m_host.Name+" is located at "+
6298 false, category+"\n"+m_host.Name+" is located at "+
6299 World.RegionInfo.RegionName+" "+ 6775 World.RegionInfo.RegionName+" "+
6300 m_host.AbsolutePosition.ToString(), 6776 m_host.AbsolutePosition.ToString(),
6301 folderID, true, m_host.AbsolutePosition, 6777 folderID, true, m_host.AbsolutePosition,
@@ -6533,13 +7009,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6533 UUID av = new UUID(); 7009 UUID av = new UUID();
6534 if (!UUID.TryParse(avatar,out av)) 7010 if (!UUID.TryParse(avatar,out av))
6535 { 7011 {
6536 LSLError("First parameter to llDialog needs to be a key"); 7012 //LSLError("First parameter to llDialog needs to be a key");
6537 return; 7013 return;
6538 } 7014 }
6539 if (buttons.Length < 1) 7015 if (buttons.Length < 1)
6540 { 7016 {
6541 LSLError("No less than 1 button can be shown"); 7017 buttons.Add("OK");
6542 return;
6543 } 7018 }
6544 if (buttons.Length > 12) 7019 if (buttons.Length > 12)
6545 { 7020 {
@@ -6556,7 +7031,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6556 } 7031 }
6557 if (buttons.Data[i].ToString().Length > 24) 7032 if (buttons.Data[i].ToString().Length > 24)
6558 { 7033 {
6559 LSLError("button label cannot be longer than 24 characters"); 7034 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6560 return; 7035 return;
6561 } 7036 }
6562 buts[i] = buttons.Data[i].ToString(); 7037 buts[i] = buttons.Data[i].ToString();
@@ -6615,22 +7090,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6615 } 7090 }
6616 7091
6617 // copy the first script found with this inventory name 7092 // copy the first script found with this inventory name
6618 lock (m_host.TaskInventory) 7093 TaskInventoryItem scriptItem = null;
7094 m_host.TaskInventory.LockItemsForRead(true);
7095 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6619 { 7096 {
6620 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7097 if (inv.Value.Name == name)
6621 { 7098 {
6622 if (inv.Value.Name == name) 7099 // make sure the object is a script
7100 if (10 == inv.Value.Type)
6623 { 7101 {
6624 // make sure the object is a script 7102 found = true;
6625 if (10 == inv.Value.Type) 7103 srcId = inv.Key;
6626 { 7104 scriptItem = inv.Value;
6627 found = true; 7105 break;
6628 srcId = inv.Key;
6629 break;
6630 }
6631 } 7106 }
6632 } 7107 }
6633 } 7108 }
7109 m_host.TaskInventory.LockItemsForRead(false);
6634 7110
6635 if (!found) 7111 if (!found)
6636 { 7112 {
@@ -6638,9 +7114,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6638 return; 7114 return;
6639 } 7115 }
6640 7116
6641 // the rest of the permission checks are done in RezScript, so check the pin there as well 7117 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6642 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7118 if (dest != null)
7119 {
7120 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7121 {
7122 // the rest of the permission checks are done in RezScript, so check the pin there as well
7123 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6643 7124
7125 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7126 m_host.Inventory.RemoveInventoryItem(srcId);
7127 }
7128 }
6644 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7129 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6645 ScriptSleep(3000); 7130 ScriptSleep(3000);
6646 } 7131 }
@@ -6703,19 +7188,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6703 public LSL_String llMD5String(string src, int nonce) 7188 public LSL_String llMD5String(string src, int nonce)
6704 { 7189 {
6705 m_host.AddScriptLPS(1); 7190 m_host.AddScriptLPS(1);
6706 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7191 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6707 } 7192 }
6708 7193
6709 public LSL_String llSHA1String(string src) 7194 public LSL_String llSHA1String(string src)
6710 { 7195 {
6711 m_host.AddScriptLPS(1); 7196 m_host.AddScriptLPS(1);
6712 return Util.SHA1Hash(src).ToLower(); 7197 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6713 } 7198 }
6714 7199
6715 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7200 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6716 { 7201 {
6717 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7202 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6718 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7203 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7204 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7205 return shapeBlock;
6719 7206
6720 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7207 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6721 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7208 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6820,6 +7307,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6820 // Prim type box, cylinder and prism. 7307 // 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) 7308 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 { 7309 {
7310 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7311 return;
7312
6823 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7313 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6824 ObjectShapePacket.ObjectDataBlock shapeBlock; 7314 ObjectShapePacket.ObjectDataBlock shapeBlock;
6825 7315
@@ -6873,6 +7363,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6873 // Prim type sphere. 7363 // 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) 7364 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6875 { 7365 {
7366 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7367 return;
7368
6876 ObjectShapePacket.ObjectDataBlock shapeBlock; 7369 ObjectShapePacket.ObjectDataBlock shapeBlock;
6877 7370
6878 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7371 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6914,6 +7407,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6914 // Prim type torus, tube and ring. 7407 // 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) 7408 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 { 7409 {
7410 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7411 return;
7412
6917 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7413 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6918 ObjectShapePacket.ObjectDataBlock shapeBlock; 7414 ObjectShapePacket.ObjectDataBlock shapeBlock;
6919 7415
@@ -7049,6 +7545,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7049 // Prim type sculpt. 7545 // Prim type sculpt.
7050 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7546 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7051 { 7547 {
7548 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7549 return;
7550
7052 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7551 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7053 UUID sculptId; 7552 UUID sculptId;
7054 7553
@@ -7073,7 +7572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7073 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7572 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7074 { 7573 {
7075 // default 7574 // default
7076 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7575 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7077 } 7576 }
7078 7577
7079 part.Shape.SetSculptProperties((byte)type, sculptId); 7578 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7089,32 +7588,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7089 ScriptSleep(200); 7588 ScriptSleep(200);
7090 } 7589 }
7091 7590
7092 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7591 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7093 { 7592 {
7094 m_host.AddScriptLPS(1); 7593 m_host.AddScriptLPS(1);
7095 7594
7096 setLinkPrimParams(linknumber, rules); 7595 setLinkPrimParams(linknumber, rules);
7596 }
7097 7597
7098 ScriptSleep(200); 7598 private void setLinkPrimParams(int linknumber, LSL_List rules)
7599 {
7600 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7601 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7602 if (parts.Count>0)
7603 {
7604 try
7605 {
7606 parts[0].ParentGroup.areUpdatesSuspended = true;
7607 foreach (SceneObjectPart part in parts)
7608 SetPrimParams(part, rules);
7609 }
7610 finally
7611 {
7612 parts[0].ParentGroup.areUpdatesSuspended = false;
7613 }
7614 }
7615 if (avatars.Count > 0)
7616 {
7617 foreach (ScenePresence avatar in avatars)
7618 SetPrimParams(avatar, rules);
7619 }
7099 } 7620 }
7100 7621
7101 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7622 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7623 float material_density, float material_friction,
7624 float material_restitution, float material_gravity_modifier)
7102 { 7625 {
7103 m_host.AddScriptLPS(1); 7626 ExtraPhysicsData physdata = new ExtraPhysicsData();
7627 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7628 physdata.Density = part.Density;
7629 physdata.Friction = part.Friction;
7630 physdata.Bounce = part.Bounciness;
7631 physdata.GravitationModifier = part.GravityModifier;
7104 7632
7105 setLinkPrimParams(linknumber, rules); 7633 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7634 physdata.Density = material_density;
7635 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7636 physdata.Friction = material_friction;
7637 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7638 physdata.Bounce = material_restitution;
7639 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7640 physdata.GravitationModifier = material_gravity_modifier;
7641
7642 part.UpdateExtraPhysics(physdata);
7106 } 7643 }
7107 7644
7108 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7645 public void llSetPhysicsMaterial(int material_bits,
7646 float material_gravity_modifier, float material_restitution,
7647 float material_friction, float material_density)
7109 { 7648 {
7110 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7649 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7650 }
7111 7651
7112 foreach (SceneObjectPart part in parts) 7652 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7113 SetPrimParams(part, rules); 7653 {
7654 llSetLinkPrimitiveParamsFast(linknumber, rules);
7655 ScriptSleep(200);
7656 }
7657
7658 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7659 {
7660 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7661 //We only support PRIM_POSITION and PRIM_ROTATION
7662
7663 int idx = 0;
7664
7665 while (idx < rules.Length)
7666 {
7667 int code = rules.GetLSLIntegerItem(idx++);
7668
7669 int remain = rules.Length - idx;
7670
7671 switch (code)
7672 {
7673 case (int)ScriptBaseClass.PRIM_POSITION:
7674 {
7675 if (remain < 1)
7676 return;
7677 LSL_Vector v;
7678 v = rules.GetVector3Item(idx++);
7679
7680 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7681 if (part == null)
7682 break;
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 v -= localPos;
7693 v /= localRot;
7694
7695 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7696
7697 v = v + 2 * sitOffset;
7698
7699 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7700 av.SendAvatarDataToAllAgents();
7701
7702 }
7703 break;
7704
7705 case (int)ScriptBaseClass.PRIM_ROTATION:
7706 {
7707 if (remain < 1)
7708 return;
7709
7710 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7711 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7712 if (llGetLinkNumber() > 1)
7713 {
7714 localRot = llGetLocalRot();
7715 localPos = llGetLocalPos();
7716 }
7717
7718 LSL_Rotation r;
7719 r = rules.GetQuaternionItem(idx++);
7720 r = r * llGetRootRotation() / localRot;
7721 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7722 av.SendAvatarDataToAllAgents();
7723 }
7724 break;
7725 }
7726 }
7114 } 7727 }
7115 7728
7116 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7729 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7117 { 7730 {
7731 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7732 return;
7733
7118 int idx = 0; 7734 int idx = 0;
7119 7735
7120 bool positionChanged = false; 7736 bool positionChanged = false;
@@ -7436,6 +8052,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7436 part.ScriptSetPhysicsStatus(physics); 8052 part.ScriptSetPhysicsStatus(physics);
7437 break; 8053 break;
7438 8054
8055 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8056 if (remain < 1)
8057 return;
8058
8059 int shape_type = rules.GetLSLIntegerItem(idx++);
8060
8061 ExtraPhysicsData physdata = new ExtraPhysicsData();
8062 physdata.Density = part.Density;
8063 physdata.Bounce = part.Bounciness;
8064 physdata.GravitationModifier = part.GravityModifier;
8065 physdata.PhysShapeType = (PhysShapeType)shape_type;
8066
8067 part.UpdateExtraPhysics(physdata);
8068
8069 break;
8070
8071 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8072 if (remain < 5)
8073 return;
8074
8075 int material_bits = rules.GetLSLIntegerItem(idx++);
8076 float material_density = (float)rules.GetLSLFloatItem(idx++);
8077 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8078 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8079 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8080
8081 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8082
8083 break;
8084
7439 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8085 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7440 if (remain < 1) 8086 if (remain < 1)
7441 return; 8087 return;
@@ -7509,7 +8155,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7509 if (part.ParentGroup.RootPart == part) 8155 if (part.ParentGroup.RootPart == part)
7510 { 8156 {
7511 SceneObjectGroup parent = part.ParentGroup; 8157 SceneObjectGroup parent = part.ParentGroup;
7512 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8158 Util.FireAndForget(delegate(object x) {
8159 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8160 });
7513 } 8161 }
7514 else 8162 else
7515 { 8163 {
@@ -7520,6 +8168,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7520 } 8168 }
7521 } 8169 }
7522 } 8170 }
8171
8172 if (positionChanged)
8173 {
8174 if (part.ParentGroup.RootPart == part)
8175 {
8176 SceneObjectGroup parent = part.ParentGroup;
8177 Util.FireAndForget(delegate(object x) {
8178 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8179 });
8180 }
8181 else
8182 {
8183 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8184 SceneObjectGroup parent = part.ParentGroup;
8185 parent.HasGroupChanged = true;
8186 parent.ScheduleGroupForTerseUpdate();
8187 }
8188 }
7523 } 8189 }
7524 8190
7525 public LSL_String llStringToBase64(string str) 8191 public LSL_String llStringToBase64(string str)
@@ -7680,13 +8346,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7680 public LSL_Integer llGetNumberOfPrims() 8346 public LSL_Integer llGetNumberOfPrims()
7681 { 8347 {
7682 m_host.AddScriptLPS(1); 8348 m_host.AddScriptLPS(1);
7683 int avatarCount = 0; 8349 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7684 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8350
7685 {
7686 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7687 avatarCount++;
7688 });
7689
7690 return m_host.ParentGroup.PrimCount + avatarCount; 8351 return m_host.ParentGroup.PrimCount + avatarCount;
7691 } 8352 }
7692 8353
@@ -7702,55 +8363,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7702 m_host.AddScriptLPS(1); 8363 m_host.AddScriptLPS(1);
7703 UUID objID = UUID.Zero; 8364 UUID objID = UUID.Zero;
7704 LSL_List result = new LSL_List(); 8365 LSL_List result = new LSL_List();
8366
8367 // If the ID is not valid, return null result
7705 if (!UUID.TryParse(obj, out objID)) 8368 if (!UUID.TryParse(obj, out objID))
7706 { 8369 {
7707 result.Add(new LSL_Vector()); 8370 result.Add(new LSL_Vector());
7708 result.Add(new LSL_Vector()); 8371 result.Add(new LSL_Vector());
7709 return result; 8372 return result;
7710 } 8373 }
8374
8375 // Check if this is an attached prim. If so, replace
8376 // the UUID with the avatar UUID and report it's bounding box
8377 SceneObjectPart part = World.GetSceneObjectPart(objID);
8378 if (part != null && part.ParentGroup.IsAttachment)
8379 objID = part.ParentGroup.AttachedAvatar;
8380
8381 // Find out if this is an avatar ID. If so, return it's box
7711 ScenePresence presence = World.GetScenePresence(objID); 8382 ScenePresence presence = World.GetScenePresence(objID);
7712 if (presence != null) 8383 if (presence != null)
7713 { 8384 {
7714 if (presence.ParentID == 0) // not sat on an object 8385 // As per LSL Wiki, there is no difference between sitting
8386 // and standing avatar since server 1.36
8387 LSL_Vector lower;
8388 LSL_Vector upper;
8389 if (presence.Animator.Animations.DefaultAnimation.AnimID
8390 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7715 { 8391 {
7716 LSL_Vector lower; 8392 // This is for ground sitting avatars
7717 LSL_Vector upper; 8393 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7718 if (presence.Animator.Animations.DefaultAnimation.AnimID 8394 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7719 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8395 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 } 8396 }
7737 else 8397 else
7738 { 8398 {
7739 // sitting on an object so we need the bounding box of that 8399 // This is for standing/flying avatars
7740 // which should include the avatar so set the UUID to the 8400 float height = presence.Appearance.AvatarHeight / 2.0f;
7741 // UUID of the object the avatar is sat on and allow it to fall through 8401 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7742 // to processing an object 8402 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7743 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7744 objID = p.UUID;
7745 } 8403 }
8404
8405 // Adjust to the documented error offsets (see LSL Wiki)
8406 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8407 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8408
8409 if (lower.x > upper.x)
8410 lower.x = upper.x;
8411 if (lower.y > upper.y)
8412 lower.y = upper.y;
8413 if (lower.z > upper.z)
8414 lower.z = upper.z;
8415
8416 result.Add(lower);
8417 result.Add(upper);
8418 return result;
7746 } 8419 }
7747 SceneObjectPart part = World.GetSceneObjectPart(objID); 8420
8421 part = World.GetSceneObjectPart(objID);
7748 // Currently only works for single prims without a sitting avatar 8422 // Currently only works for single prims without a sitting avatar
7749 if (part != null) 8423 if (part != null)
7750 { 8424 {
7751 Vector3 halfSize = part.Scale / 2.0f; 8425 float minX;
7752 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8426 float maxX;
7753 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8427 float minY;
8428 float maxY;
8429 float minZ;
8430 float maxZ;
8431
8432 // This BBox is in sim coordinates, with the offset being
8433 // a contained point.
8434 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8435 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8436
8437 minX -= offsets[0].X;
8438 maxX -= offsets[0].X;
8439 minY -= offsets[0].Y;
8440 maxY -= offsets[0].Y;
8441 minZ -= offsets[0].Z;
8442 maxZ -= offsets[0].Z;
8443
8444 LSL_Vector lower;
8445 LSL_Vector upper;
8446
8447 // Adjust to the documented error offsets (see LSL Wiki)
8448 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8449 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8450
8451 if (lower.x > upper.x)
8452 lower.x = upper.x;
8453 if (lower.y > upper.y)
8454 lower.y = upper.y;
8455 if (lower.z > upper.z)
8456 lower.z = upper.z;
8457
7754 result.Add(lower); 8458 result.Add(lower);
7755 result.Add(upper); 8459 result.Add(upper);
7756 return result; 8460 return result;
@@ -7764,7 +8468,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7764 8468
7765 public LSL_Vector llGetGeometricCenter() 8469 public LSL_Vector llGetGeometricCenter()
7766 { 8470 {
7767 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8471 Vector3 tmp = m_host.GetGeometricCenter();
8472 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7768 } 8473 }
7769 8474
7770 public LSL_List llGetPrimitiveParams(LSL_List rules) 8475 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7830,13 +8535,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7830 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8535 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7831 part.AbsolutePosition.Y, 8536 part.AbsolutePosition.Y,
7832 part.AbsolutePosition.Z); 8537 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); 8538 res.Add(v);
7841 break; 8539 break;
7842 8540
@@ -8007,56 +8705,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8007 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8705 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8008 if (remain < 1) 8706 if (remain < 1)
8009 return res; 8707 return res;
8010 8708 face = (int)rules.GetLSLIntegerItem(idx++);
8011 face=(int)rules.GetLSLIntegerItem(idx++);
8012 8709
8013 tex = part.Shape.Textures; 8710 tex = part.Shape.Textures;
8711 int shiny;
8014 if (face == ScriptBaseClass.ALL_SIDES) 8712 if (face == ScriptBaseClass.ALL_SIDES)
8015 { 8713 {
8016 for (face = 0; face < GetNumberOfSides(part); face++) 8714 for (face = 0; face < GetNumberOfSides(part); face++)
8017 { 8715 {
8018 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8716 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8019 // Convert Shininess to PRIM_SHINY_* 8717 if (shinyness == Shininess.High)
8020 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8718 {
8021 // PRIM_BUMP_* 8719 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8022 res.Add(new LSL_Integer((int)texface.Bump)); 8720 }
8721 else if (shinyness == Shininess.Medium)
8722 {
8723 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8724 }
8725 else if (shinyness == Shininess.Low)
8726 {
8727 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8728 }
8729 else
8730 {
8731 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8732 }
8733 res.Add(new LSL_Integer(shiny));
8734 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8023 } 8735 }
8024 } 8736 }
8025 else 8737 else
8026 { 8738 {
8027 if (face >= 0 && face < GetNumberOfSides(part)) 8739 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8740 if (shinyness == Shininess.High)
8028 { 8741 {
8029 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8742 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8030 // Convert Shininess to PRIM_SHINY_* 8743 }
8031 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8744 else if (shinyness == Shininess.Medium)
8032 // PRIM_BUMP_* 8745 {
8033 res.Add(new LSL_Integer((int)texface.Bump)); 8746 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8034 } 8747 }
8748 else if (shinyness == Shininess.Low)
8749 {
8750 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8751 }
8752 else
8753 {
8754 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8755 }
8756 res.Add(new LSL_Integer(shiny));
8757 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8035 } 8758 }
8036 break; 8759 break;
8037 8760
8038 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8761 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8039 if (remain < 1) 8762 if (remain < 1)
8040 return res; 8763 return res;
8041 8764 face = (int)rules.GetLSLIntegerItem(idx++);
8042 face=(int)rules.GetLSLIntegerItem(idx++);
8043 8765
8044 tex = part.Shape.Textures; 8766 tex = part.Shape.Textures;
8767 int fullbright;
8045 if (face == ScriptBaseClass.ALL_SIDES) 8768 if (face == ScriptBaseClass.ALL_SIDES)
8046 { 8769 {
8047 for (face = 0; face < GetNumberOfSides(part); face++) 8770 for (face = 0; face < GetNumberOfSides(part); face++)
8048 { 8771 {
8049 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8772 if (tex.GetFace((uint)face).Fullbright == true)
8050 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8773 {
8774 fullbright = ScriptBaseClass.TRUE;
8775 }
8776 else
8777 {
8778 fullbright = ScriptBaseClass.FALSE;
8779 }
8780 res.Add(new LSL_Integer(fullbright));
8051 } 8781 }
8052 } 8782 }
8053 else 8783 else
8054 { 8784 {
8055 if (face >= 0 && face < GetNumberOfSides(part)) 8785 if (tex.GetFace((uint)face).Fullbright == true)
8056 { 8786 {
8057 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8787 fullbright = ScriptBaseClass.TRUE;
8058 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8059 } 8788 }
8789 else
8790 {
8791 fullbright = ScriptBaseClass.FALSE;
8792 }
8793 res.Add(new LSL_Integer(fullbright));
8060 } 8794 }
8061 break; 8795 break;
8062 8796
@@ -8078,27 +8812,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8078 break; 8812 break;
8079 8813
8080 case (int)ScriptBaseClass.PRIM_TEXGEN: 8814 case (int)ScriptBaseClass.PRIM_TEXGEN:
8815 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8081 if (remain < 1) 8816 if (remain < 1)
8082 return res; 8817 return res;
8083 8818 face = (int)rules.GetLSLIntegerItem(idx++);
8084 face=(int)rules.GetLSLIntegerItem(idx++);
8085 8819
8086 tex = part.Shape.Textures; 8820 tex = part.Shape.Textures;
8087 if (face == ScriptBaseClass.ALL_SIDES) 8821 if (face == ScriptBaseClass.ALL_SIDES)
8088 { 8822 {
8089 for (face = 0; face < GetNumberOfSides(part); face++) 8823 for (face = 0; face < GetNumberOfSides(part); face++)
8090 { 8824 {
8091 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8825 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8092 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8826 {
8093 res.Add(new LSL_Integer((uint)texgen >> 1)); 8827 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8828 }
8829 else
8830 {
8831 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8832 }
8094 } 8833 }
8095 } 8834 }
8096 else 8835 else
8097 { 8836 {
8098 if (face >= 0 && face < GetNumberOfSides(part)) 8837 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8838 {
8839 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8840 }
8841 else
8099 { 8842 {
8100 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8843 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8101 res.Add(new LSL_Integer((uint)texgen >> 1));
8102 } 8844 }
8103 } 8845 }
8104 break; 8846 break;
@@ -8121,28 +8863,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8121 case (int)ScriptBaseClass.PRIM_GLOW: 8863 case (int)ScriptBaseClass.PRIM_GLOW:
8122 if (remain < 1) 8864 if (remain < 1)
8123 return res; 8865 return res;
8124 8866 face = (int)rules.GetLSLIntegerItem(idx++);
8125 face=(int)rules.GetLSLIntegerItem(idx++);
8126 8867
8127 tex = part.Shape.Textures; 8868 tex = part.Shape.Textures;
8869 float primglow;
8128 if (face == ScriptBaseClass.ALL_SIDES) 8870 if (face == ScriptBaseClass.ALL_SIDES)
8129 { 8871 {
8130 for (face = 0; face < GetNumberOfSides(part); face++) 8872 for (face = 0; face < GetNumberOfSides(part); face++)
8131 { 8873 {
8132 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8874 primglow = tex.GetFace((uint)face).Glow;
8133 res.Add(new LSL_Float(texface.Glow)); 8875 res.Add(new LSL_Float(primglow));
8134 } 8876 }
8135 } 8877 }
8136 else 8878 else
8137 { 8879 {
8138 if (face >= 0 && face < GetNumberOfSides(part)) 8880 primglow = tex.GetFace((uint)face).Glow;
8139 { 8881 res.Add(new LSL_Float(primglow));
8140 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8141 res.Add(new LSL_Float(texface.Glow));
8142 }
8143 } 8882 }
8144 break; 8883 break;
8145
8146 case (int)ScriptBaseClass.PRIM_TEXT: 8884 case (int)ScriptBaseClass.PRIM_TEXT:
8147 Color4 textColor = part.GetTextColor(); 8885 Color4 textColor = part.GetTextColor();
8148 res.Add(new LSL_String(part.Text)); 8886 res.Add(new LSL_String(part.Text));
@@ -8755,8 +9493,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8755 // The function returns an ordered list 9493 // The function returns an ordered list
8756 // representing the tokens found in the supplied 9494 // representing the tokens found in the supplied
8757 // sources string. If two successive tokenizers 9495 // sources string. If two successive tokenizers
8758 // are encountered, then a NULL entry is added 9496 // are encountered, then a null-string entry is
8759 // to the list. 9497 // added to the list.
8760 // 9498 //
8761 // It is a precondition that the source and 9499 // It is a precondition that the source and
8762 // toekizer lisst are non-null. If they are null, 9500 // toekizer lisst are non-null. If they are null,
@@ -8764,7 +9502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8764 // while their lengths are being determined. 9502 // while their lengths are being determined.
8765 // 9503 //
8766 // A small amount of working memoryis required 9504 // A small amount of working memoryis required
8767 // of approximately 8*#tokenizers. 9505 // of approximately 8*#tokenizers + 8*srcstrlen.
8768 // 9506 //
8769 // There are many ways in which this function 9507 // There are many ways in which this function
8770 // can be implemented, this implementation is 9508 // can be implemented, this implementation is
@@ -8780,155 +9518,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8780 // and eliminates redundant tokenizers as soon 9518 // and eliminates redundant tokenizers as soon
8781 // as is possible. 9519 // as is possible.
8782 // 9520 //
8783 // The implementation tries to avoid any copying 9521 // The implementation tries to minimize temporary
8784 // of arrays or other objects. 9522 // garbage generation.
8785 // </remarks> 9523 // </remarks>
8786 9524
8787 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9525 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8788 { 9526 {
8789 int beginning = 0; 9527 return ParseString2List(src, separators, spacers, true);
8790 int srclen = src.Length; 9528 }
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 9529
8805 LSL_List tokens = new LSL_List(); 9530 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9531 {
9532 int srclen = src.Length;
9533 int seplen = separators.Length;
9534 object[] separray = separators.Data;
9535 int spclen = spacers.Length;
9536 object[] spcarray = spacers.Data;
9537 int dellen = 0;
9538 string[] delarray = new string[seplen+spclen];
8806 9539
8807 // All entries are initially valid 9540 int outlen = 0;
9541 string[] outarray = new string[srclen*2+1];
8808 9542
8809 for (int i = 0; i < mlen; i++) 9543 int i, j;
8810 active[i] = true; 9544 string d;
8811 9545
8812 offset[mlen] = srclen; 9546 m_host.AddScriptLPS(1);
8813 9547
8814 while (beginning < srclen) 9548 /*
9549 * Convert separator and spacer lists to C# strings.
9550 * Also filter out null strings so we don't hang.
9551 */
9552 for (i = 0; i < seplen; i ++)
8815 { 9553 {
9554 d = separray[i].ToString();
9555 if (d.Length > 0)
9556 {
9557 delarray[dellen++] = d;
9558 }
9559 }
9560 seplen = dellen;
8816 9561
8817 best = mlen; // as bad as it gets 9562 for (i = 0; i < spclen; i ++)
9563 {
9564 d = spcarray[i].ToString();
9565 if (d.Length > 0)
9566 {
9567 delarray[dellen++] = d;
9568 }
9569 }
8818 9570
8819 // Scan for separators 9571 /*
9572 * Scan through source string from beginning to end.
9573 */
9574 for (i = 0;;)
9575 {
8820 9576
8821 for (j = 0; j < seplen; j++) 9577 /*
9578 * Find earliest delimeter in src starting at i (if any).
9579 */
9580 int earliestDel = -1;
9581 int earliestSrc = srclen;
9582 string earliestStr = null;
9583 for (j = 0; j < dellen; j ++)
8822 { 9584 {
8823 if (separray[j].ToString() == String.Empty) 9585 d = delarray[j];
8824 active[j] = false; 9586 if (d != null)
8825
8826 if (active[j])
8827 { 9587 {
8828 // scan all of the markers 9588 int index = src.IndexOf(d, i);
8829 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9589 if (index < 0)
8830 { 9590 {
8831 // not present at all 9591 delarray[j] = null; // delim nowhere in src, don't check it anymore
8832 active[j] = false;
8833 } 9592 }
8834 else 9593 else if (index < earliestSrc)
8835 { 9594 {
8836 // present and correct 9595 earliestSrc = index; // where delimeter starts in source string
8837 if (offset[j] < offset[best]) 9596 earliestDel = j; // where delimeter is in delarray[]
8838 { 9597 earliestStr = d; // the delimeter string from delarray[]
8839 // closest so far 9598 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 } 9599 }
8845 } 9600 }
8846 } 9601 }
8847 9602
8848 // Scan for spacers 9603 /*
8849 9604 * Output source string starting at i through start of earliest delimeter.
8850 if (offset[best] != beginning) 9605 */
9606 if (keepNulls || (earliestSrc > i))
8851 { 9607 {
8852 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9608 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 } 9609 }
8877 9610
8878 // This is the normal exit from the scanning loop 9611 /*
9612 * If no delimeter found at or after i, we're done scanning.
9613 */
9614 if (earliestDel < 0) break;
8879 9615
8880 if (best == mlen) 9616 /*
9617 * If delimeter was a spacer, output the spacer.
9618 */
9619 if (earliestDel >= seplen)
8881 { 9620 {
8882 // no markers were found on this pass 9621 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 } 9622 }
8888 9623
8889 // Otherwise we just add the newly delimited token 9624 /*
8890 // and recalculate where the search should continue. 9625 * Look at rest of src string following delimeter.
8891 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9626 */
8892 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9627 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 } 9628 }
8906 9629
8907 // This an awkward an not very intuitive boundary case. If the 9630 /*
8908 // last substring is a tokenizer, then there is an implied trailing 9631 * 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 9632 */
8910 // arduous. Alternatively the 'break' could be replced with a return 9633 object[] outlist = new object[outlen];
8911 // but that's shabby programming. 9634 for (i = 0; i < outlen; i ++)
8912
8913 if ((beginning == srclen) && (keepNulls))
8914 { 9635 {
8915 if (srclen != 0) 9636 outlist[i] = new LSL_String(outarray[i]);
8916 tokens.Add(new LSL_String(""));
8917 } 9637 }
8918 9638 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 } 9639 }
8933 9640
8934 public LSL_Integer llGetObjectPermMask(int mask) 9641 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9005,28 +9712,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9005 { 9712 {
9006 m_host.AddScriptLPS(1); 9713 m_host.AddScriptLPS(1);
9007 9714
9008 lock (m_host.TaskInventory) 9715 m_host.TaskInventory.LockItemsForRead(true);
9716 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9009 { 9717 {
9010 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9718 if (inv.Value.Name == item)
9011 { 9719 {
9012 if (inv.Value.Name == item) 9720 m_host.TaskInventory.LockItemsForRead(false);
9721 switch (mask)
9013 { 9722 {
9014 switch (mask) 9723 case 0:
9015 { 9724 return (int)inv.Value.BasePermissions;
9016 case 0: 9725 case 1:
9017 return (int)inv.Value.BasePermissions; 9726 return (int)inv.Value.CurrentPermissions;
9018 case 1: 9727 case 2:
9019 return (int)inv.Value.CurrentPermissions; 9728 return (int)inv.Value.GroupPermissions;
9020 case 2: 9729 case 3:
9021 return (int)inv.Value.GroupPermissions; 9730 return (int)inv.Value.EveryonePermissions;
9022 case 3: 9731 case 4:
9023 return (int)inv.Value.EveryonePermissions; 9732 return (int)inv.Value.NextPermissions;
9024 case 4:
9025 return (int)inv.Value.NextPermissions;
9026 }
9027 } 9733 }
9028 } 9734 }
9029 } 9735 }
9736 m_host.TaskInventory.LockItemsForRead(false);
9030 9737
9031 return -1; 9738 return -1;
9032 } 9739 }
@@ -9073,16 +9780,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9073 { 9780 {
9074 m_host.AddScriptLPS(1); 9781 m_host.AddScriptLPS(1);
9075 9782
9076 lock (m_host.TaskInventory) 9783 m_host.TaskInventory.LockItemsForRead(true);
9784 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9077 { 9785 {
9078 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9786 if (inv.Value.Name == item)
9079 { 9787 {
9080 if (inv.Value.Name == item) 9788 m_host.TaskInventory.LockItemsForRead(false);
9081 { 9789 return inv.Value.CreatorID.ToString();
9082 return inv.Value.CreatorID.ToString();
9083 }
9084 } 9790 }
9085 } 9791 }
9792 m_host.TaskInventory.LockItemsForRead(false);
9086 9793
9087 llSay(0, "No item name '" + item + "'"); 9794 llSay(0, "No item name '" + item + "'");
9088 9795
@@ -9224,9 +9931,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9224 { 9931 {
9225 try 9932 try
9226 { 9933 {
9934 /*
9227 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9935 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9228 if (obj != null) 9936 if (obj != null)
9229 return (double)obj.GetMass(); 9937 return (double)obj.GetMass();
9938 */
9939 // return total object mass
9940 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9941 if (obj != null)
9942 return obj.GetMass();
9943
9230 // the object is null so the key is for an avatar 9944 // the object is null so the key is for an avatar
9231 ScenePresence avatar = World.GetScenePresence(key); 9945 ScenePresence avatar = World.GetScenePresence(key);
9232 if (avatar != null) 9946 if (avatar != null)
@@ -9246,7 +9960,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 } 9960 }
9247 9961
9248 /// <summary> 9962 /// <summary>
9249 /// illListReplaceList removes the sub-list defined by the inclusive indices 9963 /// llListReplaceList removes the sub-list defined by the inclusive indices
9250 /// start and end and inserts the src list in its place. The inclusive 9964 /// 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 9965 /// 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 9966 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9303,16 +10017,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9303 // based upon end. Note that if end exceeds the upper 10017 // based upon end. Note that if end exceeds the upper
9304 // bound in this case, the entire destination list 10018 // bound in this case, the entire destination list
9305 // is removed. 10019 // is removed.
9306 else 10020 else if (start == 0)
9307 { 10021 {
9308 if (end + 1 < dest.Length) 10022 if (end + 1 < dest.Length)
9309 {
9310 return src + dest.GetSublist(end + 1, -1); 10023 return src + dest.GetSublist(end + 1, -1);
9311 }
9312 else 10024 else
9313 {
9314 return src; 10025 return src;
9315 } 10026 }
10027 else // Start < 0
10028 {
10029 if (end + 1 < dest.Length)
10030 return dest.GetSublist(end + 1, -1);
10031 else
10032 return new LSL_List();
9316 } 10033 }
9317 } 10034 }
9318 // Finally, if start > end, we strip away a prefix and 10035 // Finally, if start > end, we strip away a prefix and
@@ -9363,17 +10080,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9363 int width = 0; 10080 int width = 0;
9364 int height = 0; 10081 int height = 0;
9365 10082
9366 ParcelMediaCommandEnum? commandToSend = null; 10083 uint commandToSend = 0;
9367 float time = 0.0f; // default is from start 10084 float time = 0.0f; // default is from start
9368 10085
9369 ScenePresence presence = null; 10086 ScenePresence presence = null;
9370 10087
9371 for (int i = 0; i < commandList.Data.Length; i++) 10088 for (int i = 0; i < commandList.Data.Length; i++)
9372 { 10089 {
9373 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10090 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9374 switch (command) 10091 switch (command)
9375 { 10092 {
9376 case ParcelMediaCommandEnum.Agent: 10093 case (uint)ParcelMediaCommandEnum.Agent:
9377 // we send only to one agent 10094 // we send only to one agent
9378 if ((i + 1) < commandList.Length) 10095 if ((i + 1) < commandList.Length)
9379 { 10096 {
@@ -9390,25 +10107,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9390 } 10107 }
9391 break; 10108 break;
9392 10109
9393 case ParcelMediaCommandEnum.Loop: 10110 case (uint)ParcelMediaCommandEnum.Loop:
9394 loop = 1; 10111 loop = 1;
9395 commandToSend = command; 10112 commandToSend = command;
9396 update = true; //need to send the media update packet to set looping 10113 update = true; //need to send the media update packet to set looping
9397 break; 10114 break;
9398 10115
9399 case ParcelMediaCommandEnum.Play: 10116 case (uint)ParcelMediaCommandEnum.Play:
9400 loop = 0; 10117 loop = 0;
9401 commandToSend = command; 10118 commandToSend = command;
9402 update = true; //need to send the media update packet to make sure it doesn't loop 10119 update = true; //need to send the media update packet to make sure it doesn't loop
9403 break; 10120 break;
9404 10121
9405 case ParcelMediaCommandEnum.Pause: 10122 case (uint)ParcelMediaCommandEnum.Pause:
9406 case ParcelMediaCommandEnum.Stop: 10123 case (uint)ParcelMediaCommandEnum.Stop:
9407 case ParcelMediaCommandEnum.Unload: 10124 case (uint)ParcelMediaCommandEnum.Unload:
9408 commandToSend = command; 10125 commandToSend = command;
9409 break; 10126 break;
9410 10127
9411 case ParcelMediaCommandEnum.Url: 10128 case (uint)ParcelMediaCommandEnum.Url:
9412 if ((i + 1) < commandList.Length) 10129 if ((i + 1) < commandList.Length)
9413 { 10130 {
9414 if (commandList.Data[i + 1] is LSL_String) 10131 if (commandList.Data[i + 1] is LSL_String)
@@ -9421,7 +10138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9421 } 10138 }
9422 break; 10139 break;
9423 10140
9424 case ParcelMediaCommandEnum.Texture: 10141 case (uint)ParcelMediaCommandEnum.Texture:
9425 if ((i + 1) < commandList.Length) 10142 if ((i + 1) < commandList.Length)
9426 { 10143 {
9427 if (commandList.Data[i + 1] is LSL_String) 10144 if (commandList.Data[i + 1] is LSL_String)
@@ -9434,7 +10151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9434 } 10151 }
9435 break; 10152 break;
9436 10153
9437 case ParcelMediaCommandEnum.Time: 10154 case (uint)ParcelMediaCommandEnum.Time:
9438 if ((i + 1) < commandList.Length) 10155 if ((i + 1) < commandList.Length)
9439 { 10156 {
9440 if (commandList.Data[i + 1] is LSL_Float) 10157 if (commandList.Data[i + 1] is LSL_Float)
@@ -9446,7 +10163,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9446 } 10163 }
9447 break; 10164 break;
9448 10165
9449 case ParcelMediaCommandEnum.AutoAlign: 10166 case (uint)ParcelMediaCommandEnum.AutoAlign:
9450 if ((i + 1) < commandList.Length) 10167 if ((i + 1) < commandList.Length)
9451 { 10168 {
9452 if (commandList.Data[i + 1] is LSL_Integer) 10169 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9460,7 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9460 } 10177 }
9461 break; 10178 break;
9462 10179
9463 case ParcelMediaCommandEnum.Type: 10180 case (uint)ParcelMediaCommandEnum.Type:
9464 if ((i + 1) < commandList.Length) 10181 if ((i + 1) < commandList.Length)
9465 { 10182 {
9466 if (commandList.Data[i + 1] is LSL_String) 10183 if (commandList.Data[i + 1] is LSL_String)
@@ -9473,7 +10190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9473 } 10190 }
9474 break; 10191 break;
9475 10192
9476 case ParcelMediaCommandEnum.Desc: 10193 case (uint)ParcelMediaCommandEnum.Desc:
9477 if ((i + 1) < commandList.Length) 10194 if ((i + 1) < commandList.Length)
9478 { 10195 {
9479 if (commandList.Data[i + 1] is LSL_String) 10196 if (commandList.Data[i + 1] is LSL_String)
@@ -9486,7 +10203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9486 } 10203 }
9487 break; 10204 break;
9488 10205
9489 case ParcelMediaCommandEnum.Size: 10206 case (uint)ParcelMediaCommandEnum.Size:
9490 if ((i + 2) < commandList.Length) 10207 if ((i + 2) < commandList.Length)
9491 { 10208 {
9492 if (commandList.Data[i + 1] is LSL_Integer) 10209 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9556,7 +10273,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9556 } 10273 }
9557 } 10274 }
9558 10275
9559 if (commandToSend != null) 10276 if (commandToSend != 0)
9560 { 10277 {
9561 // the commandList contained a start/stop/... command, too 10278 // the commandList contained a start/stop/... command, too
9562 if (presence == null) 10279 if (presence == null)
@@ -9593,7 +10310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9593 10310
9594 if (aList.Data[i] != null) 10311 if (aList.Data[i] != null)
9595 { 10312 {
9596 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10313 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9597 { 10314 {
9598 case ParcelMediaCommandEnum.Url: 10315 case ParcelMediaCommandEnum.Url:
9599 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10316 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9636,16 +10353,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 { 10353 {
9637 m_host.AddScriptLPS(1); 10354 m_host.AddScriptLPS(1);
9638 10355
9639 lock (m_host.TaskInventory) 10356 m_host.TaskInventory.LockItemsForRead(true);
10357 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9640 { 10358 {
9641 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10359 if (inv.Value.Name == name)
9642 { 10360 {
9643 if (inv.Value.Name == name) 10361 m_host.TaskInventory.LockItemsForRead(false);
9644 { 10362 return inv.Value.Type;
9645 return inv.Value.Type;
9646 }
9647 } 10363 }
9648 } 10364 }
10365 m_host.TaskInventory.LockItemsForRead(false);
9649 10366
9650 return -1; 10367 return -1;
9651 } 10368 }
@@ -9656,15 +10373,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 10373
9657 if (quick_pay_buttons.Data.Length < 4) 10374 if (quick_pay_buttons.Data.Length < 4)
9658 { 10375 {
9659 LSLError("List must have at least 4 elements"); 10376 int x;
9660 return; 10377 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10378 {
10379 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10380 }
9661 } 10381 }
9662 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10382 int[] nPrice = new int[5];
9663 10383 nPrice[0] = price;
9664 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10384 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9665 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10385 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9666 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10386 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9667 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10387 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10388 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9668 m_host.ParentGroup.HasGroupChanged = true; 10389 m_host.ParentGroup.HasGroupChanged = true;
9669 } 10390 }
9670 10391
@@ -9680,8 +10401,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 ShoutError("No permissions to track the camera"); 10401 ShoutError("No permissions to track the camera");
9681 return new LSL_Vector(); 10402 return new LSL_Vector();
9682 } 10403 }
10404 m_host.TaskInventory.LockItemsForRead(false);
9683 10405
9684 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10406// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10407 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9685 if (presence != null) 10408 if (presence != null)
9686 { 10409 {
9687 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10410 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9702,8 +10425,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9702 ShoutError("No permissions to track the camera"); 10425 ShoutError("No permissions to track the camera");
9703 return new LSL_Rotation(); 10426 return new LSL_Rotation();
9704 } 10427 }
10428 m_host.TaskInventory.LockItemsForRead(false);
9705 10429
9706 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10430// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10431 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9707 if (presence != null) 10432 if (presence != null)
9708 { 10433 {
9709 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10434 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9763,8 +10488,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9763 { 10488 {
9764 m_host.AddScriptLPS(1); 10489 m_host.AddScriptLPS(1);
9765 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10490 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9766 if (detectedParams == null) return; // only works on the first detected avatar 10491 if (detectedParams == null)
9767 10492 {
10493 if (m_host.ParentGroup.IsAttachment == true)
10494 {
10495 detectedParams = new DetectParams();
10496 detectedParams.Key = m_host.OwnerID;
10497 }
10498 else
10499 {
10500 return;
10501 }
10502 }
10503
9768 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10504 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9769 if (avatar != null) 10505 if (avatar != null)
9770 { 10506 {
@@ -9772,6 +10508,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9772 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10508 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9773 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10509 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9774 } 10510 }
10511
9775 ScriptSleep(1000); 10512 ScriptSleep(1000);
9776 } 10513 }
9777 10514
@@ -9895,12 +10632,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9895 10632
9896 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10633 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9897 object[] data = rules.Data; 10634 object[] data = rules.Data;
9898 for (int i = 0; i < data.Length; ++i) { 10635 for (int i = 0; i < data.Length; ++i)
10636 {
9899 int type = Convert.ToInt32(data[i++].ToString()); 10637 int type = Convert.ToInt32(data[i++].ToString());
9900 if (i >= data.Length) break; // odd number of entries => ignore the last 10638 if (i >= data.Length) break; // odd number of entries => ignore the last
9901 10639
9902 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10640 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9903 switch (type) { 10641 switch (type)
10642 {
9904 case ScriptBaseClass.CAMERA_FOCUS: 10643 case ScriptBaseClass.CAMERA_FOCUS:
9905 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10644 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9906 case ScriptBaseClass.CAMERA_POSITION: 10645 case ScriptBaseClass.CAMERA_POSITION:
@@ -10006,19 +10745,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10006 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10745 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10007 { 10746 {
10008 m_host.AddScriptLPS(1); 10747 m_host.AddScriptLPS(1);
10009 string ret = String.Empty; 10748
10010 string src1 = llBase64ToString(str1); 10749 if (str1 == String.Empty)
10011 string src2 = llBase64ToString(str2); 10750 return String.Empty;
10012 int c = 0; 10751 if (str2 == String.Empty)
10013 for (int i = 0; i < src1.Length; i++) 10752 return str1;
10753
10754 int len = str2.Length;
10755 if ((len % 4) != 0) // LL is EVIL!!!!
10756 {
10757 while (str2.EndsWith("="))
10758 str2 = str2.Substring(0, str2.Length - 1);
10759
10760 len = str2.Length;
10761 int mod = len % 4;
10762
10763 if (mod == 1)
10764 str2 = str2.Substring(0, str2.Length - 1);
10765 else if (mod == 2)
10766 str2 += "==";
10767 else if (mod == 3)
10768 str2 += "=";
10769 }
10770
10771 byte[] data1;
10772 byte[] data2;
10773 try
10774 {
10775 data1 = Convert.FromBase64String(str1);
10776 data2 = Convert.FromBase64String(str2);
10777 }
10778 catch (Exception)
10014 { 10779 {
10015 ret += (char) (src1[i] ^ src2[c]); 10780 return new LSL_String(String.Empty);
10781 }
10016 10782
10017 c++; 10783 byte[] d2 = new Byte[data1.Length];
10018 if (c >= src2.Length) 10784 int pos = 0;
10019 c = 0; 10785
10786 if (data1.Length <= data2.Length)
10787 {
10788 Array.Copy(data2, 0, d2, 0, data1.Length);
10789 }
10790 else
10791 {
10792 while (pos < data1.Length)
10793 {
10794 len = data1.Length - pos;
10795 if (len > data2.Length)
10796 len = data2.Length;
10797
10798 Array.Copy(data2, 0, d2, pos, len);
10799 pos += len;
10800 }
10020 } 10801 }
10021 return llStringToBase64(ret); 10802
10803 for (pos = 0 ; pos < data1.Length ; pos++ )
10804 data1[pos] ^= d2[pos];
10805
10806 return Convert.ToBase64String(data1);
10022 } 10807 }
10023 10808
10024 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10809 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10075,12 +10860,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10075 Regex r = new Regex(authregex); 10860 Regex r = new Regex(authregex);
10076 int[] gnums = r.GetGroupNumbers(); 10861 int[] gnums = r.GetGroupNumbers();
10077 Match m = r.Match(url); 10862 Match m = r.Match(url);
10078 if (m.Success) { 10863 if (m.Success)
10079 for (int i = 1; i < gnums.Length; i++) { 10864 {
10865 for (int i = 1; i < gnums.Length; i++)
10866 {
10080 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10867 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10081 //CaptureCollection cc = g.Captures; 10868 //CaptureCollection cc = g.Captures;
10082 } 10869 }
10083 if (m.Groups.Count == 5) { 10870 if (m.Groups.Count == 5)
10871 {
10084 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10872 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(); 10873 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10086 } 10874 }
@@ -10443,15 +11231,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10443 11231
10444 internal UUID ScriptByName(string name) 11232 internal UUID ScriptByName(string name)
10445 { 11233 {
10446 lock (m_host.TaskInventory) 11234 m_host.TaskInventory.LockItemsForRead(true);
11235
11236 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10447 { 11237 {
10448 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11238 if (item.Type == 10 && item.Name == name)
10449 { 11239 {
10450 if (item.Type == 10 && item.Name == name) 11240 m_host.TaskInventory.LockItemsForRead(false);
10451 return item.ItemID; 11241 return item.ItemID;
10452 } 11242 }
10453 } 11243 }
10454 11244
11245 m_host.TaskInventory.LockItemsForRead(false);
11246
10455 return UUID.Zero; 11247 return UUID.Zero;
10456 } 11248 }
10457 11249
@@ -10492,6 +11284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10492 { 11284 {
10493 m_host.AddScriptLPS(1); 11285 m_host.AddScriptLPS(1);
10494 11286
11287 //Clone is thread safe
10495 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11288 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10496 11289
10497 UUID assetID = UUID.Zero; 11290 UUID assetID = UUID.Zero;
@@ -10554,6 +11347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10554 { 11347 {
10555 m_host.AddScriptLPS(1); 11348 m_host.AddScriptLPS(1);
10556 11349
11350 //Clone is thread safe
10557 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11351 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10558 11352
10559 UUID assetID = UUID.Zero; 11353 UUID assetID = UUID.Zero;
@@ -10634,15 +11428,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10634 return GetLinkPrimitiveParams(obj, rules); 11428 return GetLinkPrimitiveParams(obj, rules);
10635 } 11429 }
10636 11430
10637 public void print(string str) 11431 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10638 { 11432 {
10639 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11433 List<SceneObjectPart> parts = GetLinkParts(link);
10640 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11434 if (parts.Count < 1)
10641 if (ossl != null) 11435 return 0;
10642 { 11436
10643 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11437 return GetNumberOfSides(parts[0]);
10644 m_log.Info("LSL print():" + str);
10645 }
10646 } 11438 }
10647 11439
10648 private string Name2Username(string name) 11440 private string Name2Username(string name)
@@ -10688,155 +11480,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10688 return rq.ToString(); 11480 return rq.ToString();
10689 } 11481 }
10690 11482
11483 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11484 {
11485 m_SayShoutCount = 0;
11486 }
11487
11488 private struct Tri
11489 {
11490 public Vector3 p1;
11491 public Vector3 p2;
11492 public Vector3 p3;
11493 }
11494
11495 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11496 {
11497 float height = avatar.Appearance.AvatarHeight;
11498 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11499 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11500
11501 if (point.X > b1.X && point.X < b2.X &&
11502 point.Y > b1.Y && point.Y < b2.Y &&
11503 point.Z > b1.Z && point.Z < b2.Z)
11504 return true;
11505 return false;
11506 }
11507
11508 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11509 {
11510 List<ContactResult> contacts = new List<ContactResult>();
11511
11512 Vector3 ab = rayEnd - rayStart;
11513
11514 World.ForEachScenePresence(delegate(ScenePresence sp)
11515 {
11516 Vector3 ac = sp.AbsolutePosition - rayStart;
11517 Vector3 bc = sp.AbsolutePosition - rayEnd;
11518
11519 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11520
11521 if (d > 1.5)
11522 return;
11523
11524 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11525
11526 if (d2 > 0)
11527 return;
11528
11529 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11530 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11531
11532 if (!InBoundingBox(sp, p))
11533 return;
11534
11535 ContactResult result = new ContactResult ();
11536 result.ConsumerID = sp.LocalId;
11537 result.Depth = Vector3.Distance(rayStart, p);
11538 result.Normal = Vector3.Zero;
11539 result.Pos = p;
11540
11541 contacts.Add(result);
11542 });
11543
11544 return contacts.ToArray();
11545 }
11546
11547 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11548 {
11549 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11550 List<ContactResult> contacts = new List<ContactResult>();
11551
11552 Vector3 ab = rayEnd - rayStart;
11553
11554 World.ForEachSOG(delegate(SceneObjectGroup group)
11555 {
11556 if (m_host.ParentGroup == group)
11557 return;
11558
11559 if (group.IsAttachment)
11560 return;
11561
11562 if (group.RootPart.PhysActor == null)
11563 {
11564 if (!includePhantom)
11565 return;
11566 }
11567 else
11568 {
11569 if (group.RootPart.PhysActor.IsPhysical)
11570 {
11571 if (!includePhysical)
11572 return;
11573 }
11574 else
11575 {
11576 if (!includeNonPhysical)
11577 return;
11578 }
11579 }
11580
11581 // Find the radius ouside of which we don't even need to hit test
11582 float minX;
11583 float maxX;
11584 float minY;
11585 float maxY;
11586 float minZ;
11587 float maxZ;
11588
11589 float radius = 0.0f;
11590
11591 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11592
11593 if (Math.Abs(minX) > radius)
11594 radius = Math.Abs(minX);
11595 if (Math.Abs(minY) > radius)
11596 radius = Math.Abs(minY);
11597 if (Math.Abs(minZ) > radius)
11598 radius = Math.Abs(minZ);
11599 if (Math.Abs(maxX) > radius)
11600 radius = Math.Abs(maxX);
11601 if (Math.Abs(maxY) > radius)
11602 radius = Math.Abs(maxY);
11603 if (Math.Abs(maxZ) > radius)
11604 radius = Math.Abs(maxZ);
11605
11606 Vector3 ac = group.AbsolutePosition - rayStart;
11607 Vector3 bc = group.AbsolutePosition - rayEnd;
11608
11609 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11610
11611 // Too far off ray, don't bother
11612 if (d > radius)
11613 return;
11614
11615 // Behind ray, drop
11616 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11617 if (d2 > 0)
11618 return;
11619
11620 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11621 // Miss.
11622 if (!intersection.HitTF)
11623 return;
11624
11625 ContactResult result = new ContactResult ();
11626 result.ConsumerID = group.LocalId;
11627 result.Depth = intersection.distance;
11628 result.Normal = intersection.normal;
11629 result.Pos = intersection.ipoint;
11630
11631 contacts.Add(result);
11632 });
11633
11634 return contacts.ToArray();
11635 }
11636
11637 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11638 {
11639 double[,] heightfield = World.Heightmap.GetDoubles();
11640 List<ContactResult> contacts = new List<ContactResult>();
11641
11642 double min = 2048.0;
11643 double max = 0.0;
11644
11645 // Find the min and max of the heightfield
11646 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11647 {
11648 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11649 {
11650 if (heightfield[x, y] > max)
11651 max = heightfield[x, y];
11652 if (heightfield[x, y] < min)
11653 min = heightfield[x, y];
11654 }
11655 }
11656
11657
11658 // A ray extends past rayEnd, but doesn't go back before
11659 // rayStart. If the start is above the highest point of the ground
11660 // and the ray goes up, we can't hit the ground. Ever.
11661 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11662 return null;
11663
11664 // Same for going down
11665 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11666 return null;
11667
11668 List<Tri> trilist = new List<Tri>();
11669
11670 // Create our triangle list
11671 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11672 {
11673 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11674 {
11675 Tri t1 = new Tri();
11676 Tri t2 = new Tri();
11677
11678 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11679 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11680 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11681 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11682
11683 t1.p1 = p1;
11684 t1.p2 = p2;
11685 t1.p3 = p3;
11686
11687 t2.p1 = p3;
11688 t2.p2 = p4;
11689 t2.p3 = p1;
11690
11691 trilist.Add(t1);
11692 trilist.Add(t2);
11693 }
11694 }
11695
11696 // Ray direction
11697 Vector3 rayDirection = rayEnd - rayStart;
11698
11699 foreach (Tri t in trilist)
11700 {
11701 // Compute triangle plane normal and edges
11702 Vector3 u = t.p2 - t.p1;
11703 Vector3 v = t.p3 - t.p1;
11704 Vector3 n = Vector3.Cross(u, v);
11705
11706 if (n == Vector3.Zero)
11707 continue;
11708
11709 Vector3 w0 = rayStart - t.p1;
11710 double a = -Vector3.Dot(n, w0);
11711 double b = Vector3.Dot(n, rayDirection);
11712
11713 // Not intersecting the plane, or in plane (same thing)
11714 // Ignoring this MAY cause the ground to not be detected
11715 // sometimes
11716 if (Math.Abs(b) < 0.000001)
11717 continue;
11718
11719 double r = a / b;
11720
11721 // ray points away from plane
11722 if (r < 0.0)
11723 continue;
11724
11725 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11726
11727 float uu = Vector3.Dot(u, u);
11728 float uv = Vector3.Dot(u, v);
11729 float vv = Vector3.Dot(v, v);
11730 Vector3 w = ip - t.p1;
11731 float wu = Vector3.Dot(w, u);
11732 float wv = Vector3.Dot(w, v);
11733 float d = uv * uv - uu * vv;
11734
11735 float cs = (uv * wv - vv * wu) / d;
11736 if (cs < 0 || cs > 1.0)
11737 continue;
11738 float ct = (uv * wu - uu * wv) / d;
11739 if (ct < 0 || (cs + ct) > 1.0)
11740 continue;
11741
11742 // Add contact point
11743 ContactResult result = new ContactResult ();
11744 result.ConsumerID = 0;
11745 result.Depth = Vector3.Distance(rayStart, ip);
11746 result.Normal = n;
11747 result.Pos = ip;
11748
11749 contacts.Add(result);
11750 }
11751
11752 if (contacts.Count == 0)
11753 return null;
11754
11755 contacts.Sort(delegate(ContactResult a, ContactResult b)
11756 {
11757 return (int)(a.Depth - b.Depth);
11758 });
11759
11760 return contacts[0];
11761 }
11762/*
11763 // not done:
11764 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11765 {
11766 ContactResult[] contacts = null;
11767 World.ForEachSOG(delegate(SceneObjectGroup group)
11768 {
11769 if (m_host.ParentGroup == group)
11770 return;
11771
11772 if (group.IsAttachment)
11773 return;
11774
11775 if(group.RootPart.PhysActor != null)
11776 return;
11777
11778 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11779 });
11780 return contacts;
11781 }
11782*/
11783
10691 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11784 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10692 { 11785 {
11786 LSL_List list = new LSL_List();
11787
10693 m_host.AddScriptLPS(1); 11788 m_host.AddScriptLPS(1);
10694 11789
10695 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11790 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); 11791 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); 11792 Vector3 dir = rayEnd - rayStart;
10698 11793
10699 int count = 0; 11794 float dist = Vector3.Mag(dir);
10700// int detectPhantom = 0; 11795
11796 int count = 1;
11797 bool detectPhantom = false;
10701 int dataFlags = 0; 11798 int dataFlags = 0;
10702 int rejectTypes = 0; 11799 int rejectTypes = 0;
10703 11800
10704 for (int i = 0; i < options.Length; i += 2) 11801 for (int i = 0; i < options.Length; i += 2)
10705 { 11802 {
10706 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11803 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10707 {
10708 count = options.GetLSLIntegerItem(i + 1); 11804 count = options.GetLSLIntegerItem(i + 1);
10709 } 11805 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10710// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11806 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10711// {
10712// detectPhantom = options.GetLSLIntegerItem(i + 1);
10713// }
10714 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11807 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10715 {
10716 dataFlags = options.GetLSLIntegerItem(i + 1); 11808 dataFlags = options.GetLSLIntegerItem(i + 1);
10717 }
10718 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11809 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10719 {
10720 rejectTypes = options.GetLSLIntegerItem(i + 1); 11810 rejectTypes = options.GetLSLIntegerItem(i + 1);
10721 }
10722 } 11811 }
10723 11812
10724 LSL_List list = new LSL_List(); 11813 if (count > 16)
10725 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11814 count = 16;
10726
10727 double distance = Util.GetDistanceTo(startvector, endvector);
10728
10729 if (distance == 0)
10730 distance = 0.001;
10731 11815
10732 Vector3 posToCheck = startvector; 11816 List<ContactResult> results = new List<ContactResult>();
10733 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10734 11817
10735 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11818 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10736 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11819 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10737 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11820 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10738 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11821 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10739 11822
10740 for (float i = 0; i <= distance; i += 0.1f) 11823
11824 if (World.SuportsRayCastFiltered())
10741 { 11825 {
10742 posToCheck = startvector + (dir * (i / (float)distance)); 11826 if (dist == 0)
11827 return list;
11828
11829 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11830 if (checkTerrain)
11831 rayfilter |= RayFilterFlags.land;
11832// if (checkAgents)
11833// rayfilter |= RayFilterFlags.agent;
11834 if (checkPhysical)
11835 rayfilter |= RayFilterFlags.physical;
11836 if (checkNonPhysical)
11837 rayfilter |= RayFilterFlags.nonphysical;
11838 if (detectPhantom)
11839 rayfilter |= RayFilterFlags.LSLPhanton;
11840
11841 Vector3 direction = dir * ( 1/dist);
10743 11842
10744 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11843 if(rayfilter == 0)
10745 { 11844 {
10746 ContactResult result = new ContactResult(); 11845 list.Add(new LSL_Integer(0));
10747 result.ConsumerID = 0; 11846 return list;
10748 result.Depth = 0;
10749 result.Normal = Vector3.Zero;
10750 result.Pos = posToCheck;
10751 results.Add(result);
10752 checkTerrain = false;
10753 } 11847 }
10754 11848
10755 if (checkAgents) 11849 // get some more contacts to sort ???
11850 int physcount = 4 * count;
11851 if (physcount > 20)
11852 physcount = 20;
11853
11854 object physresults;
11855 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11856
11857 if (physresults == null)
10756 { 11858 {
10757 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11859 list.Add(new LSL_Integer(-3)); // timeout error
10758 { 11860 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 } 11861 }
10770 }
10771 11862
10772 int refcount = 0; 11863 results = (List<ContactResult>)physresults;
10773 foreach (ContactResult result in results) 11864
10774 { 11865 // for now physics doesn't detect sitted avatars so do it outside physics
10775 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11866 if (checkAgents)
10776 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11867 {
10777 continue; 11868 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11869 foreach (ContactResult r in agentHits)
11870 results.Add(r);
11871 }
10778 11872
10779 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11873 // bug: will not detect phantom unless they are physical
11874 // don't use ObjectIntersection because its also bad
10780 11875
10781 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11876 }
10782 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11877 else
11878 {
11879 if (checkTerrain)
11880 {
11881 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11882 if (groundContact != null)
11883 results.Add((ContactResult)groundContact);
11884 }
10783 11885
10784 if (entity == null) 11886 if (checkAgents)
10785 { 11887 {
10786 list.Add(UUID.Zero); 11888 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11889 foreach (ContactResult r in agentHits)
11890 results.Add(r);
11891 }
10787 11892
10788 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11893 if (checkPhysical || checkNonPhysical || detectPhantom)
10789 list.Add(0); 11894 {
11895 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11896 foreach (ContactResult r in objectHits)
11897 results.Add(r);
11898 }
11899 }
10790 11900
10791 list.Add(result.Pos); 11901 results.Sort(delegate(ContactResult a, ContactResult b)
11902 {
11903 return a.Depth.CompareTo(b.Depth);
11904 });
11905
11906 int values = 0;
11907 SceneObjectGroup thisgrp = m_host.ParentGroup;
10792 11908
10793 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11909 foreach (ContactResult result in results)
10794 list.Add(result.Normal); 11910 {
11911 if (result.Depth > dist)
11912 continue;
10795 11913
10796 continue; //Can't find it, so add UUID.Zero 11914 // physics ray can return colisions with host prim
10797 } 11915 if (m_host.LocalId == result.ConsumerID)
11916 continue;
10798 11917
10799 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11918 UUID itemID = UUID.Zero;
10800 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11919 int linkNum = 0;
10801 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10802 11920
10803 if (entity is SceneObjectPart) 11921 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11922 // It's a prim!
11923 if (part != null)
10804 { 11924 {
10805 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11925 // dont detect members of same object ???
11926 if (part.ParentGroup == thisgrp)
11927 continue;
10806 11928
10807 if (pa != null && pa.IsPhysical) 11929 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10808 { 11930 itemID = part.ParentGroup.UUID;
10809 if (!checkPhysical)
10810 continue;
10811 }
10812 else 11931 else
10813 { 11932 itemID = part.UUID;
10814 if (!checkNonPhysical)
10815 continue;
10816 }
10817 }
10818 11933
10819 refcount++; 11934 linkNum = part.LinkNum;
10820 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11935 }
10821 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10822 else 11936 else
10823 list.Add(entity.UUID);
10824
10825 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10826 { 11937 {
10827 if (entity is SceneObjectPart) 11938 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10828 list.Add(((SceneObjectPart)entity).LinkNum); 11939 /// It it a boy? a girl?
10829 else 11940 if (sp != null)
10830 list.Add(0); 11941 itemID = sp.UUID;
10831 } 11942 }
10832 11943
10833 list.Add(result.Pos); 11944 list.Add(new LSL_String(itemID.ToString()));
11945 list.Add(new LSL_String(result.Pos.ToString()));
11946
11947 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11948 list.Add(new LSL_Integer(linkNum));
10834 11949
10835 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11950 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10836 list.Add(result.Normal); 11951 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11952
11953 values++;
11954 if (values >= count)
11955 break;
10837 } 11956 }
10838 11957
10839 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11958 list.Add(new LSL_Integer(values));
10840 11959
10841 return list; 11960 return list;
10842 } 11961 }
@@ -10876,7 +11995,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10876 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11995 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10877 if (!isAccount) return 0; 11996 if (!isAccount) return 0;
10878 if (estate.HasAccess(id)) return 1; 11997 if (estate.HasAccess(id)) return 1;
10879 if (estate.IsBanned(id)) 11998 if (estate.IsBanned(id, World.GetUserFlags(id)))
10880 estate.RemoveBan(id); 11999 estate.RemoveBan(id);
10881 estate.AddEstateUser(id); 12000 estate.AddEstateUser(id);
10882 break; 12001 break;
@@ -10895,14 +12014,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10895 break; 12014 break;
10896 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12015 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10897 if (!isAccount) return 0; 12016 if (!isAccount) return 0;
10898 if (estate.IsBanned(id)) return 1; 12017 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10899 EstateBan ban = new EstateBan(); 12018 EstateBan ban = new EstateBan();
10900 ban.EstateID = estate.EstateID; 12019 ban.EstateID = estate.EstateID;
10901 ban.BannedUserID = id; 12020 ban.BannedUserID = id;
10902 estate.AddBan(ban); 12021 estate.AddBan(ban);
10903 break; 12022 break;
10904 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12023 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10905 if (!isAccount || !estate.IsBanned(id)) return 0; 12024 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10906 estate.RemoveBan(id); 12025 estate.RemoveBan(id);
10907 break; 12026 break;
10908 default: return 0; 12027 default: return 0;
@@ -10931,7 +12050,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10931 return 16384; 12050 return 16384;
10932 } 12051 }
10933 12052
10934 public LSL_Integer llGetUsedMemory() 12053 public virtual LSL_Integer llGetUsedMemory()
10935 { 12054 {
10936 m_host.AddScriptLPS(1); 12055 m_host.AddScriptLPS(1);
10937 // The value returned for LSO scripts in SL 12056 // The value returned for LSO scripts in SL
@@ -10959,7 +12078,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10959 public void llSetSoundQueueing(int queue) 12078 public void llSetSoundQueueing(int queue)
10960 { 12079 {
10961 m_host.AddScriptLPS(1); 12080 m_host.AddScriptLPS(1);
10962 NotImplemented("llSetSoundQueueing");
10963 } 12081 }
10964 12082
10965 public void llCollisionSprite(string impact_sprite) 12083 public void llCollisionSprite(string impact_sprite)
@@ -10971,10 +12089,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10971 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12089 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10972 { 12090 {
10973 m_host.AddScriptLPS(1); 12091 m_host.AddScriptLPS(1);
10974 NotImplemented("llGodLikeRezObject"); 12092
12093 if (!World.Permissions.IsGod(m_host.OwnerID))
12094 NotImplemented("llGodLikeRezObject");
12095
12096 AssetBase rezAsset = World.AssetService.Get(inventory);
12097 if (rezAsset == null)
12098 {
12099 llSay(0, "Asset not found");
12100 return;
12101 }
12102
12103 SceneObjectGroup group = null;
12104
12105 try
12106 {
12107 string xmlData = Utils.BytesToString(rezAsset.Data);
12108 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12109 }
12110 catch
12111 {
12112 llSay(0, "Asset not found");
12113 return;
12114 }
12115
12116 if (group == null)
12117 {
12118 llSay(0, "Asset not found");
12119 return;
12120 }
12121
12122 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12123 group.RootPart.AttachOffset = group.AbsolutePosition;
12124
12125 group.ResetIDs();
12126
12127 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12128 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12129 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12130 group.ScheduleGroupForFullUpdate();
12131
12132 // objects rezzed with this method are die_at_edge by default.
12133 group.RootPart.SetDieAtEdge(true);
12134
12135 group.ResumeScripts();
12136
12137 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12138 "object_rez", new Object[] {
12139 new LSL_String(
12140 group.RootPart.UUID.ToString()) },
12141 new DetectParams[0]));
12142 }
12143
12144 public LSL_String llTransferLindenDollars(string destination, int amount)
12145 {
12146 UUID txn = UUID.Random();
12147
12148 Util.FireAndForget(delegate(object x)
12149 {
12150 int replycode = 0;
12151 string replydata = destination + "," + amount.ToString();
12152
12153 try
12154 {
12155 TaskInventoryItem item = m_item;
12156 if (item == null)
12157 {
12158 replydata = "SERVICE_ERROR";
12159 return;
12160 }
12161
12162 m_host.AddScriptLPS(1);
12163
12164 if (item.PermsGranter == UUID.Zero)
12165 {
12166 replydata = "MISSING_PERMISSION_DEBIT";
12167 return;
12168 }
12169
12170 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12171 {
12172 replydata = "MISSING_PERMISSION_DEBIT";
12173 return;
12174 }
12175
12176 UUID toID = new UUID();
12177
12178 if (!UUID.TryParse(destination, out toID))
12179 {
12180 replydata = "INVALID_AGENT";
12181 return;
12182 }
12183
12184 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12185
12186 if (money == null)
12187 {
12188 replydata = "TRANSFERS_DISABLED";
12189 return;
12190 }
12191
12192 bool result = money.ObjectGiveMoney(
12193 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12194
12195 if (result)
12196 {
12197 replycode = 1;
12198 return;
12199 }
12200
12201 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12202 }
12203 finally
12204 {
12205 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12206 "transaction_result", new Object[] {
12207 new LSL_String(txn.ToString()),
12208 new LSL_Integer(replycode),
12209 new LSL_String(replydata) },
12210 new DetectParams[0]));
12211 }
12212 });
12213
12214 return txn.ToString();
10975 } 12215 }
10976 12216
10977 #endregion 12217 #endregion
12218
12219 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12220 {
12221 SceneObjectGroup group = m_host.ParentGroup;
12222
12223 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12224 return;
12225 if (group.IsAttachment)
12226 return;
12227
12228 if (frames.Data.Length > 0) // We are getting a new motion
12229 {
12230 if (group.RootPart.KeyframeMotion != null)
12231 group.RootPart.KeyframeMotion.Stop();
12232 group.RootPart.KeyframeMotion = null;
12233
12234 int idx = 0;
12235
12236 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12237 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12238
12239 while (idx < options.Data.Length)
12240 {
12241 int option = (int)options.GetLSLIntegerItem(idx++);
12242 int remain = options.Data.Length - idx;
12243
12244 switch (option)
12245 {
12246 case ScriptBaseClass.KFM_MODE:
12247 if (remain < 1)
12248 break;
12249 int modeval = (int)options.GetLSLIntegerItem(idx++);
12250 switch(modeval)
12251 {
12252 case ScriptBaseClass.KFM_FORWARD:
12253 mode = KeyframeMotion.PlayMode.Forward;
12254 break;
12255 case ScriptBaseClass.KFM_REVERSE:
12256 mode = KeyframeMotion.PlayMode.Reverse;
12257 break;
12258 case ScriptBaseClass.KFM_LOOP:
12259 mode = KeyframeMotion.PlayMode.Loop;
12260 break;
12261 case ScriptBaseClass.KFM_PING_PONG:
12262 mode = KeyframeMotion.PlayMode.PingPong;
12263 break;
12264 }
12265 break;
12266 case ScriptBaseClass.KFM_DATA:
12267 if (remain < 1)
12268 break;
12269 int dataval = (int)options.GetLSLIntegerItem(idx++);
12270 data = (KeyframeMotion.DataFormat)dataval;
12271 break;
12272 }
12273 }
12274
12275 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12276
12277 idx = 0;
12278
12279 int elemLength = 2;
12280 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12281 elemLength = 3;
12282
12283 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12284 while (idx < frames.Data.Length)
12285 {
12286 int remain = frames.Data.Length - idx;
12287
12288 if (remain < elemLength)
12289 break;
12290
12291 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12292 frame.Position = null;
12293 frame.Rotation = null;
12294
12295 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12296 {
12297 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12298 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12299 }
12300 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12301 {
12302 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12303 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12304 }
12305
12306 float tempf = (float)frames.GetLSLFloatItem(idx++);
12307 frame.TimeMS = (int)(tempf * 1000.0f);
12308
12309 keyframes.Add(frame);
12310 }
12311
12312 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12313 group.RootPart.KeyframeMotion.Start();
12314 }
12315 else
12316 {
12317 if (group.RootPart.KeyframeMotion == null)
12318 return;
12319
12320 if (options.Data.Length == 0)
12321 {
12322 group.RootPart.KeyframeMotion.Stop();
12323 return;
12324 }
12325
12326 int code = (int)options.GetLSLIntegerItem(0);
12327
12328 int idx = 0;
12329
12330 while (idx < options.Data.Length)
12331 {
12332 int option = (int)options.GetLSLIntegerItem(idx++);
12333 int remain = options.Data.Length - idx;
12334
12335 switch (option)
12336 {
12337 case ScriptBaseClass.KFM_COMMAND:
12338 int cmd = (int)options.GetLSLIntegerItem(idx++);
12339 switch (cmd)
12340 {
12341 case ScriptBaseClass.KFM_CMD_PLAY:
12342 group.RootPart.KeyframeMotion.Start();
12343 break;
12344 case ScriptBaseClass.KFM_CMD_STOP:
12345 group.RootPart.KeyframeMotion.Stop();
12346 break;
12347 case ScriptBaseClass.KFM_CMD_PAUSE:
12348 group.RootPart.KeyframeMotion.Pause();
12349 break;
12350 }
12351 break;
12352 }
12353 }
12354 }
12355 }
10978 } 12356 }
10979 12357
10980 public class NotecardCache 12358 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);